mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-23 18:41:48 -08:00
refactor(editor): Migrate InlineNameEdit
& InlineTextEdit
components to Vue 3 syntax (no-changelog) (#9755)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
parent
b7aea957b8
commit
c0a6acaef6
|
@ -5,7 +5,6 @@
|
|||
</span>
|
||||
<div
|
||||
v-else
|
||||
v-on-click-outside="disableNameEdit"
|
||||
:class="[$style.headline, $style['headline-editable']]"
|
||||
@keydown.stop
|
||||
@click="enableNameEdit"
|
||||
|
@ -31,66 +30,53 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { onClickOutside } from '@vueuse/core';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InlineNameEdit',
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
subtitle: {
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
...useToast(),
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isNameEdit: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onNameEdit(value: string) {
|
||||
this.$emit('update:modelValue', value);
|
||||
},
|
||||
enableNameEdit() {
|
||||
this.isNameEdit = true;
|
||||
interface Props {
|
||||
modelValue: string;
|
||||
subtitle: string;
|
||||
type: string;
|
||||
readonly: boolean;
|
||||
}
|
||||
const props = defineProps<Props>();
|
||||
|
||||
setTimeout(() => {
|
||||
const inputRef = this.$refs.nameInput as HTMLInputElement | undefined;
|
||||
if (inputRef) {
|
||||
inputRef.focus();
|
||||
}
|
||||
}, 0);
|
||||
},
|
||||
disableNameEdit() {
|
||||
if (!this.modelValue) {
|
||||
this.$emit('update:modelValue', `Untitled ${this.type}`);
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', value: string): void;
|
||||
}>();
|
||||
|
||||
this.showToast({
|
||||
title: 'Error',
|
||||
message: `${this.type} name cannot be empty`,
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
const isNameEdit = ref(false);
|
||||
const nameInput = ref<HTMLInputElement | null>(null);
|
||||
const { showToast } = useToast();
|
||||
|
||||
this.isNameEdit = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
const onNameEdit = (value: string) => {
|
||||
emit('update:modelValue', value);
|
||||
};
|
||||
|
||||
const enableNameEdit = () => {
|
||||
isNameEdit.value = true;
|
||||
void nextTick(() => {
|
||||
if (nameInput.value) {
|
||||
nameInput.value.focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const disableNameEdit = () => {
|
||||
if (!props.modelValue) {
|
||||
emit('update:modelValue', `Untitled ${props.type}`);
|
||||
showToast({
|
||||
title: 'Error',
|
||||
message: `${props.type} name cannot be empty`,
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
isNameEdit.value = false;
|
||||
};
|
||||
|
||||
onClickOutside(nameInput, disableNameEdit);
|
||||
</script>
|
||||
|
||||
<style module lang="scss">
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<span class="inline-edit" @keydown.stop>
|
||||
<span v-if="isEditEnabled && !isDisabled">
|
||||
<ExpandableInputEdit
|
||||
v-model="newValue"
|
||||
:placeholder="placeholder"
|
||||
:model-value="newValue"
|
||||
:maxlength="maxLength"
|
||||
:autofocus="true"
|
||||
:event-bus="inputBus"
|
||||
|
@ -20,106 +20,84 @@
|
|||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, defineProps, defineEmits } from 'vue';
|
||||
import ExpandableInputEdit from '@/components/ExpandableInput/ExpandableInputEdit.vue';
|
||||
import ExpandableInputPreview from '@/components/ExpandableInput/ExpandableInputPreview.vue';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InlineTextEdit',
|
||||
components: { ExpandableInputEdit, ExpandableInputPreview },
|
||||
props: {
|
||||
isEditEnabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
previewValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
isEditEnabled: boolean;
|
||||
modelValue: string;
|
||||
placeholder: string;
|
||||
maxLength: number;
|
||||
previewValue: string;
|
||||
disabled: boolean;
|
||||
}>(),
|
||||
{
|
||||
isEditEnabled: false,
|
||||
modelValue: '',
|
||||
placeholder: '',
|
||||
maxLength: 0,
|
||||
previewValue: '',
|
||||
disabled: false,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDisabled: this.disabled,
|
||||
newValue: '',
|
||||
escPressed: false,
|
||||
inputBus: createEventBus(),
|
||||
};
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'toggle'): void;
|
||||
(event: 'submit', payload: { name: string; onSubmit: (updated: boolean) => void }): void;
|
||||
}>();
|
||||
|
||||
const isDisabled = ref(props.disabled);
|
||||
const newValue = ref('');
|
||||
const escPressed = ref(false);
|
||||
const inputBus = ref(createEventBus());
|
||||
|
||||
watch(
|
||||
() => props.disabled,
|
||||
(value) => {
|
||||
isDisabled.value = value;
|
||||
},
|
||||
watch: {
|
||||
disabled(value) {
|
||||
this.isDisabled = value;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onInput(newValue: string) {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
||||
this.newValue = newValue;
|
||||
},
|
||||
onClick() {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
function onInput(val: string) {
|
||||
if (isDisabled.value) return;
|
||||
newValue.value = val;
|
||||
}
|
||||
|
||||
this.newValue = this.modelValue;
|
||||
this.$emit('toggle');
|
||||
},
|
||||
onBlur() {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
function onClick() {
|
||||
if (isDisabled.value) return;
|
||||
newValue.value = props.modelValue;
|
||||
emit('toggle');
|
||||
}
|
||||
|
||||
if (!this.escPressed) {
|
||||
this.submit();
|
||||
}
|
||||
this.escPressed = false;
|
||||
},
|
||||
submit() {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
function onBlur() {
|
||||
if (isDisabled.value) return;
|
||||
if (!escPressed.value) {
|
||||
submit();
|
||||
}
|
||||
escPressed.value = false;
|
||||
}
|
||||
|
||||
const onSubmit = (updated: boolean) => {
|
||||
this.isDisabled = false;
|
||||
function submit() {
|
||||
if (isDisabled.value) return;
|
||||
const onSubmit = (updated: boolean) => {
|
||||
isDisabled.value = false;
|
||||
if (!updated) {
|
||||
inputBus.value.emit('focus');
|
||||
}
|
||||
};
|
||||
isDisabled.value = true;
|
||||
emit('submit', { name: newValue.value, onSubmit });
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
this.inputBus.emit('focus');
|
||||
}
|
||||
};
|
||||
|
||||
this.isDisabled = true;
|
||||
this.$emit('submit', { name: this.newValue, onSubmit });
|
||||
},
|
||||
onEscape() {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.escPressed = true;
|
||||
this.$emit('toggle');
|
||||
},
|
||||
},
|
||||
});
|
||||
function onEscape() {
|
||||
if (isDisabled.value) return;
|
||||
escPressed.value = true;
|
||||
emit('toggle');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
Loading…
Reference in a new issue