refactor(editor): Convert some smaller components to composition api (no-changelog) (#11546)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions

Co-authored-by: Ricardo Espinoza <ricardo@n8n.io>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2024-11-05 02:09:34 +01:00 committed by GitHub
parent 611967decc
commit 6854f94875
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 107 additions and 118 deletions

View file

@ -1,26 +1,25 @@
<script lang="ts"> <script setup lang="ts">
import { type PropType, defineComponent } from 'vue'; import { computed } from 'vue';
import type { EnterpriseEditionFeatureValue } from '@/Interface'; import type { EnterpriseEditionFeatureValue } from '@/Interface';
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store'; import { useSettingsStore } from '@/stores/settings.store';
export default defineComponent({ const props = withDefaults(
name: 'EnterpriseEdition', defineProps<{
props: { features: EnterpriseEditionFeatureValue[];
features: { }>(),
type: Array as PropType<EnterpriseEditionFeatureValue[]>, {
default: () => [], features: () => [],
},
}, },
computed: { );
...mapStores(useSettingsStore),
canAccess(): boolean { const settingsStore = useSettingsStore();
return this.features.reduce((acc: boolean, feature) => {
return acc && !!this.settingsStore.isEnterpriseFeatureEnabled[feature]; const canAccess = computed(() =>
}, true); props.features.reduce(
}, (acc: boolean, feature) => acc && !!settingsStore.isEnterpriseFeatureEnabled[feature],
}, true,
}); ),
);
</script> </script>
<template> <template>

View file

@ -1,26 +1,23 @@
<script lang="ts"> <script setup lang="ts">
import { defineComponent } from 'vue'; import { computed } from 'vue';
import { mapStores } from 'pinia';
import { useRootStore } from '@/stores/root.store'; import { useRootStore } from '@/stores/root.store';
import { useI18n } from '@/composables/useI18n';
export default defineComponent({ const rootStore = useRootStore();
name: 'PushConnectionTracker', const pushConnectionActive = computed(() => rootStore.pushConnectionActive);
computed: { const i18n = useI18n();
...mapStores(useRootStore),
},
});
</script> </script>
<template> <template>
<span> <span>
<div v-if="!rootStore.pushConnectionActive" class="push-connection-lost primary-color"> <div v-if="!pushConnectionActive" class="push-connection-lost primary-color">
<n8n-tooltip placement="bottom-end"> <n8n-tooltip placement="bottom-end">
<template #content> <template #content>
<div v-n8n-html="$locale.baseText('pushConnectionTracker.cannotConnectToServer')"></div> <div v-n8n-html="i18n.baseText('pushConnectionTracker.cannotConnectToServer')"></div>
</template> </template>
<span> <span>
<font-awesome-icon icon="exclamation-triangle" />&nbsp; <font-awesome-icon icon="exclamation-triangle" />&nbsp;
{{ $locale.baseText('pushConnectionTracker.connectionLost') }} {{ i18n.baseText('pushConnectionTracker.connectionLost') }}
</span> </span>
</n8n-tooltip> </n8n-tooltip>
</div> </div>

View file

@ -1,98 +1,91 @@
<script lang="ts"> <script setup lang="ts">
import { defineComponent } from 'vue'; import { ref, computed, watch, onBeforeMount } from 'vue';
import { EnterpriseEditionFeature } from '@/constants'; import { EnterpriseEditionFeature } from '@/constants';
import { mapStores } from 'pinia';
import { useProjectsStore } from '@/stores/projects.store'; import { useProjectsStore } from '@/stores/projects.store';
import type { PropType } from 'vue';
import type { ProjectSharingData } from '@/types/projects.types'; import type { ProjectSharingData } from '@/types/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue'; import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
import type { IFilters } from '../layouts/ResourcesListLayout.vue';
import { useI18n } from '@/composables/useI18n';
export type IResourceFiltersType = Record<string, boolean | string | string[]>; type IResourceFiltersType = Record<string, boolean | string | string[]>;
export default defineComponent({ const props = withDefaults(
components: { defineProps<{
ProjectSharing, modelValue?: IResourceFiltersType;
keys?: string[];
shareable?: boolean;
reset?: () => void;
}>(),
{
modelValue: () => ({}),
keys: () => [],
shareable: true,
reset: () => {},
}, },
props: { );
modelValue: {
type: Object as PropType<IResourceFiltersType>,
default: () => ({}),
},
keys: {
type: Array as PropType<string[]>,
default: () => [],
},
shareable: {
type: Boolean,
default: true,
},
reset: {
type: Function as PropType<() => void>,
default: () => {},
},
},
data() {
return {
EnterpriseEditionFeature,
selectedProject: null as ProjectSharingData | null,
};
},
computed: {
...mapStores(useProjectsStore),
filtersLength(): number {
let length = 0;
this.keys.forEach((key) => { const emit = defineEmits<{
if (key === 'search') { 'update:modelValue': [value: IFilters];
return; 'update:filtersLength': [value: number];
} }>();
const value = this.modelValue[key]; const selectedProject = ref<ProjectSharingData | null>(null);
length += (Array.isArray(value) ? value.length > 0 : value !== '') ? 1 : 0;
});
return length; const projectsStore = useProjectsStore();
},
hasFilters(): boolean {
return this.filtersLength > 0;
},
},
watch: {
filtersLength(value: number) {
this.$emit('update:filtersLength', value);
},
},
async beforeMount() {
await this.projectsStore.getAvailableProjects();
this.selectedProject =
this.projectsStore.availableProjects.find(
(project) => project.id === this.modelValue.homeProject,
) ?? null;
},
methods: {
setKeyValue(key: string, value: unknown) {
const filters = {
...this.modelValue,
[key]: value,
};
this.$emit('update:modelValue', filters); const i18n = useI18n();
},
resetFilters() {
if (this.reset) {
this.reset();
} else {
const filters = { ...this.modelValue };
this.keys.forEach((key) => { const filtersLength = computed(() => {
filters[key] = Array.isArray(this.modelValue[key]) ? [] : ''; let length = 0;
});
this.$emit('update:modelValue', filters); props.keys.forEach((key) => {
} if (key === 'search') {
this.selectedProject = null; return;
}, }
},
const value = props.modelValue[key];
length += (Array.isArray(value) ? value.length > 0 : value !== '') ? 1 : 0;
});
return length;
});
const hasFilters = computed(() => filtersLength.value > 0);
const setKeyValue = (key: string, value: unknown) => {
const filters = {
...props.modelValue,
[key]: value,
} as IFilters;
emit('update:modelValue', filters);
};
const resetFilters = () => {
if (props.reset) {
props.reset();
} else {
const filters = { ...props.modelValue } as IFilters;
props.keys.forEach((key) => {
filters[key] = Array.isArray(props.modelValue[key]) ? [] : '';
});
emit('update:modelValue', filters);
}
selectedProject.value = null;
};
watch(filtersLength, (value) => {
emit('update:filtersLength', value);
});
onBeforeMount(async () => {
await projectsStore.getAvailableProjects();
selectedProject.value =
projectsStore.availableProjects.find(
(project) => project.id === props.modelValue.homeProject,
) ?? null;
}); });
</script> </script>
@ -109,7 +102,7 @@ export default defineComponent({
<n8n-badge v-show="filtersLength > 0" theme="primary" class="mr-4xs"> <n8n-badge v-show="filtersLength > 0" theme="primary" class="mr-4xs">
{{ filtersLength }} {{ filtersLength }}
</n8n-badge> </n8n-badge>
{{ $locale.baseText('forms.resourceFiltersDropdown.filters') }} {{ i18n.baseText('forms.resourceFiltersDropdown.filters') }}
</n8n-button> </n8n-button>
</template> </template>
<div :class="$style['filters-dropdown']" data-test-id="resources-list-filters-dropdown"> <div :class="$style['filters-dropdown']" data-test-id="resources-list-filters-dropdown">
@ -119,7 +112,7 @@ export default defineComponent({
:features="[EnterpriseEditionFeature.Sharing]" :features="[EnterpriseEditionFeature.Sharing]"
> >
<n8n-input-label <n8n-input-label
:label="$locale.baseText('forms.resourceFiltersDropdown.owner')" :label="i18n.baseText('forms.resourceFiltersDropdown.owner')"
:bold="false" :bold="false"
size="small" size="small"
color="text-base" color="text-base"
@ -128,14 +121,14 @@ export default defineComponent({
<ProjectSharing <ProjectSharing
v-model="selectedProject" v-model="selectedProject"
:projects="projectsStore.availableProjects" :projects="projectsStore.availableProjects"
:placeholder="$locale.baseText('forms.resourceFiltersDropdown.owner.placeholder')" :placeholder="i18n.baseText('forms.resourceFiltersDropdown.owner.placeholder')"
:empty-options-text="$locale.baseText('projects.sharing.noMatchingProjects')" :empty-options-text="i18n.baseText('projects.sharing.noMatchingProjects')"
@update:model-value="setKeyValue('homeProject', ($event as ProjectSharingData).id)" @update:model-value="setKeyValue('homeProject', ($event as ProjectSharingData).id)"
/> />
</enterprise-edition> </enterprise-edition>
<div v-if="hasFilters" :class="[$style['filters-dropdown-footer'], 'mt-s']"> <div v-if="hasFilters" :class="[$style['filters-dropdown-footer'], 'mt-s']">
<n8n-link @click="resetFilters"> <n8n-link @click="resetFilters">
{{ $locale.baseText('forms.resourceFiltersDropdown.reset') }} {{ i18n.baseText('forms.resourceFiltersDropdown.reset') }}
</n8n-link> </n8n-link>
</div> </div>
</div> </div>