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