mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat(editor): Refactor several smaller components to composition API (no-changelog) (#10038)
This commit is contained in:
parent
2e9ab66602
commit
c4c25eadfd
|
@ -35,51 +35,41 @@
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
interface Props {
|
||||||
name: 'Banner',
|
theme: 'success' | 'danger';
|
||||||
props: {
|
message: string;
|
||||||
theme: {
|
buttonLabel?: string;
|
||||||
type: String,
|
buttonLoadingLabel?: string;
|
||||||
validator: (value: string): boolean => ['success', 'danger'].indexOf(value) !== -1,
|
buttonTitle?: string;
|
||||||
},
|
details?: string;
|
||||||
message: {
|
buttonLoading?: boolean;
|
||||||
type: String,
|
}
|
||||||
},
|
|
||||||
buttonLabel: {
|
withDefaults(defineProps<Props>(), {
|
||||||
type: String,
|
buttonLoading: false,
|
||||||
},
|
buttonLabel: '',
|
||||||
buttonLoadingLabel: {
|
buttonLoadingLabel: '',
|
||||||
type: String,
|
buttonTitle: '',
|
||||||
},
|
details: '',
|
||||||
buttonTitle: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
details: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
buttonLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
expanded: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
expand() {
|
|
||||||
this.expanded = true;
|
|
||||||
},
|
|
||||||
onClick() {
|
|
||||||
this.expanded = false;
|
|
||||||
this.$emit('click');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
click: [];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const expanded = ref(false);
|
||||||
|
|
||||||
|
const expand = () => {
|
||||||
|
expanded.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClick = () => {
|
||||||
|
expanded.value = false;
|
||||||
|
emit('click');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<n8n-card :class="$style.card" v-bind="$attrs">
|
<n8n-card :class="$style.card" v-bind="$attrs">
|
||||||
<template v-if="!loading" #header>
|
<template v-if="!loading && title" #header>
|
||||||
<span :class="$style.title" v-text="title" />
|
<span :class="$style.title" v-text="title" />
|
||||||
</template>
|
</template>
|
||||||
<n8n-loading :loading="loading" :rows="3" variant="p" />
|
<n8n-loading :loading="loading" :rows="3" variant="p" />
|
||||||
|
@ -10,20 +10,11 @@
|
||||||
</n8n-card>
|
</n8n-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
defineProps<{
|
||||||
|
loading: boolean;
|
||||||
export default defineComponent({
|
title?: string;
|
||||||
name: 'Card',
|
}>();
|
||||||
props: {
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
|
|
@ -5,27 +5,15 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { useRouter } from 'vue-router';
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
|
|
||||||
export default defineComponent({
|
const router = useRouter();
|
||||||
name: 'GoBackButton',
|
|
||||||
data() {
|
const navigateTo = () => {
|
||||||
return {
|
void router.push({ name: VIEWS.TEMPLATES });
|
||||||
routeHasHistory: false,
|
};
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
window.history.state ? (this.routeHasHistory = true) : (this.routeHasHistory = false);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
navigateTo() {
|
|
||||||
if (this.routeHasHistory) this.$router.go(-1);
|
|
||||||
else void this.$router.push({ name: VIEWS.TEMPLATES });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="scroll">
|
|
||||||
<div class="content">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'PageContentWrapper',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.wrapper {
|
|
||||||
padding-top: 40px;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 40px);
|
|
||||||
}
|
|
||||||
.scroll {
|
|
||||||
overflow-y: auto;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
padding: 1em;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -119,7 +119,7 @@
|
||||||
|
|
||||||
<TextEdit
|
<TextEdit
|
||||||
:dialog-visible="textEditDialogVisible"
|
:dialog-visible="textEditDialogVisible"
|
||||||
:model-value="modelValue"
|
:model-value="`${modelValue}`"
|
||||||
:parameter="parameter"
|
:parameter="parameter"
|
||||||
:path="path"
|
:path="path"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
|
|
|
@ -4,24 +4,24 @@
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { shorten } from '@/utils/typesUtils';
|
import { shorten } from '@/utils/typesUtils';
|
||||||
|
|
||||||
const DEFAULT_WORKFLOW_NAME_LIMIT = 25;
|
const DEFAULT_WORKFLOW_NAME_LIMIT = 25;
|
||||||
const WORKFLOW_NAME_END_COUNT_TO_KEEP = 4;
|
const WORKFLOW_NAME_END_COUNT_TO_KEEP = 4;
|
||||||
|
|
||||||
export default defineComponent({
|
interface Props {
|
||||||
name: 'ShortenName',
|
name: string;
|
||||||
props: ['name', 'limit', 'testId'],
|
testId: string;
|
||||||
computed: {
|
limit?: number;
|
||||||
shortenedName(): string {
|
}
|
||||||
return shorten(
|
|
||||||
this.name,
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
this.limit || DEFAULT_WORKFLOW_NAME_LIMIT,
|
limit: DEFAULT_WORKFLOW_NAME_LIMIT,
|
||||||
WORKFLOW_NAME_END_COUNT_TO_KEEP,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const shortenedName = computed(() =>
|
||||||
|
shorten(props.name, props.limit, WORKFLOW_NAME_END_COUNT_TO_KEEP),
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -17,14 +17,6 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'NoTagsView',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
$--footer-spacing: 45px;
|
$--footer-spacing: 45px;
|
||||||
|
|
||||||
|
|
|
@ -27,33 +27,35 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
||||||
|
|
||||||
export default defineComponent({
|
withDefaults(
|
||||||
props: {
|
defineProps<{
|
||||||
disabled: {
|
disabled: boolean;
|
||||||
default: false,
|
search: string;
|
||||||
},
|
}>(),
|
||||||
search: {
|
{
|
||||||
default: '',
|
disabled: false,
|
||||||
},
|
search: '',
|
||||||
},
|
},
|
||||||
data() {
|
);
|
||||||
return {
|
|
||||||
maxLength: MAX_TAG_NAME_LENGTH,
|
const emit = defineEmits<{
|
||||||
};
|
searchChange: [value: string];
|
||||||
},
|
createEnable: [];
|
||||||
methods: {
|
}>();
|
||||||
onAddNew() {
|
|
||||||
this.$emit('createEnable');
|
const maxLength = ref(MAX_TAG_NAME_LENGTH);
|
||||||
},
|
|
||||||
onSearchChange(search: string) {
|
const onAddNew = () => {
|
||||||
this.$emit('searchChange', search);
|
emit('createEnable');
|
||||||
},
|
};
|
||||||
},
|
|
||||||
});
|
const onSearchChange = (search: string) => {
|
||||||
|
emit('searchChange', search);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -9,17 +9,10 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
defineProps<{
|
||||||
|
title: string;
|
||||||
export default defineComponent({
|
}>();
|
||||||
name: 'TemplateDetailsBlock',
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
>
|
>
|
||||||
<div class="ignore-key-press">
|
<div class="ignore-key-press">
|
||||||
<n8n-input-label :label="$locale.nodeText().inputLabelDisplayName(parameter, path)">
|
<n8n-input-label :label="$locale.nodeText().inputLabelDisplayName(parameter, path)">
|
||||||
<div @keydown.stop @keydown.esc="onKeyDownEsc()">
|
<div @keydown.stop @keydown.esc="onKeyDownEsc">
|
||||||
<n8n-input
|
<n8n-input
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
v-model="tempValue"
|
v-model="tempValue"
|
||||||
|
@ -28,49 +28,60 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, defineComponent } from 'vue';
|
import { ref, watch, onMounted, nextTick } from 'vue';
|
||||||
|
import type { INodeProperties } from 'n8n-workflow';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps<{
|
||||||
name: 'TextEdit',
|
dialogVisible: boolean;
|
||||||
props: ['dialogVisible', 'parameter', 'path', 'modelValue', 'isReadOnly'],
|
parameter: INodeProperties;
|
||||||
data() {
|
path: string;
|
||||||
return {
|
modelValue: string;
|
||||||
tempValue: '', // el-input does not seem to work without v-model so add one
|
isReadOnly: boolean;
|
||||||
};
|
}>();
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
async dialogVisible() {
|
|
||||||
if (this.dialogVisible === true) {
|
|
||||||
await nextTick();
|
|
||||||
(this.$refs.inputField as HTMLInputElement).focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modelValue(value: string) {
|
|
||||||
this.tempValue = value;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.tempValue = this.modelValue as string;
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
valueChanged(value: string) {
|
|
||||||
this.$emit('update:modelValue', value);
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeyDownEsc() {
|
const emit = defineEmits<{
|
||||||
// Resetting input value when closing the dialog, required when closing it using the `Esc` key
|
'update:modelValue': [value: string];
|
||||||
this.tempValue = this.modelValue;
|
closeDialog: [];
|
||||||
|
}>();
|
||||||
|
|
||||||
this.closeDialog();
|
const inputField = ref<HTMLInputElement | null>(null);
|
||||||
},
|
const tempValue = ref('');
|
||||||
|
|
||||||
closeDialog() {
|
watch(
|
||||||
// Handle the close externally as the visible parameter is an external prop
|
() => props.dialogVisible,
|
||||||
// and is so not allowed to be changed here.
|
async (newValue) => {
|
||||||
this.$emit('closeDialog');
|
if (newValue) {
|
||||||
return false;
|
await nextTick();
|
||||||
},
|
inputField.value?.focus();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(value: string) => {
|
||||||
|
tempValue.value = value;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
tempValue.value = props.modelValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const valueChanged = (value: string) => {
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyDownEsc = () => {
|
||||||
|
// Resetting input value when closing the dialog, required when closing it using the `Esc` key
|
||||||
|
tempValue.value = props.modelValue;
|
||||||
|
closeDialog();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
// Handle the close externally as the visible parameter is an external prop
|
||||||
|
// and is so not allowed to be changed here.
|
||||||
|
emit('closeDialog');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -7,22 +7,11 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { type PropType, defineComponent } from 'vue';
|
defineProps<{
|
||||||
|
title: string;
|
||||||
export default defineComponent({
|
items: string[];
|
||||||
name: 'TitledList',
|
}>();
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
items: {
|
|
||||||
type: Array as PropType<string[]>,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.titled-list {
|
.titled-list {
|
||||||
|
|
|
@ -4,14 +4,6 @@
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'SlideTransition',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.slide-leave-active,
|
.slide-leave-active,
|
||||||
.slide-enter-active {
|
.slide-enter-active {
|
||||||
|
|
Loading…
Reference in a new issue