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:
oleg 2024-06-20 10:38:08 +02:00 committed by GitHub
parent b7aea957b8
commit c0a6acaef6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 110 additions and 146 deletions

View file

@ -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();
const isNameEdit = ref(false);
const nameInput = ref<HTMLInputElement | null>(null);
const { showToast } = useToast();
const onNameEdit = (value: string) => {
emit('update:modelValue', value);
};
const enableNameEdit = () => {
isNameEdit.value = true;
void nextTick(() => {
if (nameInput.value) {
nameInput.value.focus();
} }
}, 0); });
}, };
disableNameEdit() {
if (!this.modelValue) {
this.$emit('update:modelValue', `Untitled ${this.type}`);
this.showToast({ const disableNameEdit = () => {
if (!props.modelValue) {
emit('update:modelValue', `Untitled ${props.type}`);
showToast({
title: 'Error', title: 'Error',
message: `${this.type} name cannot be empty`, message: `${props.type} name cannot be empty`,
type: 'warning', type: 'warning',
}); });
} }
isNameEdit.value = false;
};
this.isNameEdit = false; onClickOutside(nameInput, disableNameEdit);
},
},
});
</script> </script>
<style module lang="scss"> <style module lang="scss">

View file

@ -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;
}>(),
{
isEditEnabled: false,
modelValue: '',
placeholder: '',
maxLength: 0,
previewValue: '',
disabled: false,
}, },
modelValue: { );
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
maxLength: {
type: Number,
default: 0,
},
previewValue: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
isDisabled: this.disabled,
newValue: '',
escPressed: false,
inputBus: createEventBus(),
};
},
watch: {
disabled(value) {
this.isDisabled = value;
},
},
methods: {
onInput(newValue: string) {
if (this.disabled) {
return;
}
this.newValue = newValue; const emit = defineEmits<{
}, (event: 'toggle'): void;
onClick() { (event: 'submit', payload: { name: string; onSubmit: (updated: boolean) => void }): void;
if (this.disabled) { }>();
return;
}
this.newValue = this.modelValue; const isDisabled = ref(props.disabled);
this.$emit('toggle'); const newValue = ref('');
}, const escPressed = ref(false);
onBlur() { const inputBus = ref(createEventBus());
if (this.disabled) {
return;
}
if (!this.escPressed) { watch(
this.submit(); () => props.disabled,
} (value) => {
this.escPressed = false; isDisabled.value = value;
}, },
submit() { );
if (this.disabled) {
return;
}
function onInput(val: string) {
if (isDisabled.value) return;
newValue.value = val;
}
function onClick() {
if (isDisabled.value) return;
newValue.value = props.modelValue;
emit('toggle');
}
function onBlur() {
if (isDisabled.value) return;
if (!escPressed.value) {
submit();
}
escPressed.value = false;
}
function submit() {
if (isDisabled.value) return;
const onSubmit = (updated: boolean) => { const onSubmit = (updated: boolean) => {
this.isDisabled = false; isDisabled.value = false;
if (!updated) { if (!updated) {
this.inputBus.emit('focus'); inputBus.value.emit('focus');
} }
}; };
isDisabled.value = true;
emit('submit', { name: newValue.value, onSubmit });
}
this.isDisabled = true; function onEscape() {
this.$emit('submit', { name: this.newValue, onSubmit }); if (isDisabled.value) return;
}, escPressed.value = true;
onEscape() { emit('toggle');
if (this.disabled) { }
return;
}
this.escPressed = true;
this.$emit('toggle');
},
},
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>