n8n/packages/design-system/src/components/N8nSticky/Sticky.vue
Mutasem Aldmour 31dd01f9cb
feat(editor): Add Workflow Stickies (Notes) (#3154)
* N8N-3029 Add Node Type for Wokrflow Stickies/Notes

* N8N-3029 Update Content, Update Aliasses

* N8N-3030 Created N8N Sticky Component in Design System

* N8N-3030 Fixed Code spaccing Sticky Component

* N8N-3030 Fixed Code spaccing StickyStories Component

* N8N-3030 Fixed Code spaccing Markdown Component

* N8N-3030 Added Sticky Colors Pallete into Storybook, Update Color Variables for Sticky Component

* N8N-3030 Added Unfocus Event

* N8N-3030 Update Default Placeholder, Markdown Styles, Fixed Edit State, Added Text to EditState, Fixed Height of Area, Turned off Resize of textarea

* N8N-3030 Update Sticky Overflow, Update Hover States, Updated Markdown Overflow

* N8N-3030, N8N-3031 - Add Resize to Sticky, Created N8n-Resize component

* N8N-3031 Fixed Importing Components in Editor-ui

* N8N-3031 Fixed Resize Component, Fixed Gradient

* N8N-3030, N8N-3031 Update Note Description

* N8N-3032 Hotfix Building Storybook

* N8N-3032 - Select Behaviour, Changes in Resize Component, Emit on Width/Height/Top/Left Change

* N8N-3032 Update Resize Component to emmit left/top, Update Dynamic Resize on Selected Background

* N8N-3032 Updated / Dragging vs Resizing, prevent open Modal for stickies

* N8N-3032 Added ID props to n8n-sticky // dynamic id for multi resizing in NodeView

* N8N-3033 Add dynamic size Tooltip on Sticky

* N8N-3033 Updated Z-index for Sticky Component

* N8N-3033 Updated N8N-Resize Component, Fixed SelectedBackround for Sticky Component

* N8N-3033 Refactor

* N8N-3033 Focus/Defocus on TextArea

* N8N-3033 Fixed Resizing on NW Point

* N8N-3030 Save content in vuex on input change

* N8N-3033 Fixed Resizer, Save Width and Height in Vue

* N8N-3033 Hide Sticky Footer on small height/width

* N8N-3033 Fixed Resizer

* N8N-3033 Dynamic Z-index for Stickies

* N8N-3033 Dynamic Z-index for Stickies

* N8N-3033 Removed static z-index for select sticky class

* N8N-3034 Added Telemetry

* N8N-3030 Formatter

* N8N-3030 Format code

* N8N-3030 Fixed Selecting Stickies

* N8N-3033 Fixed Notifications

* N8N-3030 Added new paddings for Default Stickies

* N8N-3033 Prevent Scrolling NodeView when Sticky is in Edit mode and Mouse is Over the TextArea

* N8N-3030 Prevent double clicking to switch state of Sticky component in Edit Mode

* N8N-3033 Fixed Z-index of Stickies

* N8N-3033 Prevent delete node when in EditMode

* N8N-3030 Prevent Delete Button to delete the Sticky while in Edit Mode

* N8N-3030 Change EditMode (emit) on keyboard shortucts, update Markdown Links & Images, Added new props

* N8N-3030 Sticky Component - No padding when hiding footer text

* N8N-3033 Fix Resizing enter into Edit Mode

* N8N-3033 Selecting different nodes - exit the edit mode

* N8N-3033 Auto Select Text in text-area by default - Sticky Component

* N8N-3033 Prevent Default behaviour for CTRL + X, CTRL + A when Sticky is Active && inEditMode

* N8N-3033 Refactor Resizer, Refactor Sticky, Update zIndex inEditMode

* N8N-3033 Updated Default Text // Node-base, Storybook

* N8N-3033 Add Resizing in EditMode - Components update

* N8N-3033 Fixed Footer - Show/Hide on Resize in EditMode

* N8N-3033 Fix ActiveSticky on Init

* N8N-3033 Refactor Sticky in Vuex, Fixed Init Sticky Tweaks, Prevent Modal Openning, Save on Keyboard shortcuts

* Stickies - Update Note node with new props

* N8N-3030 Updated Default Note text, Update the Markdown Link

* N8N-3030 CMD-C does not copy the text fix

* N8N-3030 Fix Max Zoom / Zoom out shortcuts disabled in editState

* N8N-3030 Z-index fixed during Edit Mode typing

* N8N-3030 Prevent Autoselect Text in Stickies if the text is not default

* N8N-3030 Fixed ReadOnly Bugs / Prevent showing Tooltip, Resizing

* N8N-3030 Added Sticky Creator Button

* N8N-3030 Update Icon / Sticky Creator Button

* N8N-3033 Update Sticky Icon / StickyCreator Button

* update package lock

* 🔩 update note props

* 🚿 clean props

* 🔧 linting

* 🔧 fix spacing

* remove resize component

* remove resize component

* ✂ clean up sticky

* revert back to height width

* revert back to height/width

* replace zindex property

* replace default text property

* use i18n to translate

* update package lock

* move resize

* clean up how height/width are set

* fix resize for sticky to support left/top

* clean up resize

* fix lasso/highlight bug

* remove unused props

* fix zoom to fit

* fix padding for demo view

* fix readonly

* remove iseditable, use active state

* clean up keyboard events

* chang button size, no edit on insert

* scale resizing correctly

* make active on resize

* fix select on resize/move

* use outline icon

* allow for multiple line breaks

* fix multi line bug

* fix edit mode outline

* keep edit open as one resizes

* respect multiple spaces

* fix scrolling bug

* clean up hover impl

* clean up references to note

* disable for rename

* fix drifting while drag

* fix mouse cursor on resize

* fix sticky min height

* refactor resize into component

* fix pulling too far bug

* fix delete/cut all bug

* fix padding bottom

* fix active change on resize

* add transition to button

* Fix sticky markdown click

* add solid fa icon

* update node graph, telemetry event

* add snapping

* change alt text

* update package lock

* fix bug in button hover

* add back transition

* clean up resize

* add grid size as param

* remove breaks

* clean up markdown

* lint fixes

* fix spacing

* clean up markdown colors

* clean up classes in resize

* clean up resize

* update sticky story

* fix spacing

* clean up classes

* revert change

* revert change

* revert change

* clean up sticky component

* remove unused component

* remove unnessary data

* remove unnessary data

* clean up actions

* clean up sticky size

* clean up unnessary border style

* fix bug

* replace sticky note name

* update description

* remove support for multi spaces

* update tracking name

* update telemetry reqs

* fix enter bug

* update alt text

* update sticky notes doc url

* fix readonly bug

* update class name

* update quote marks

Co-authored-by: SchnapsterDog <olivertrajceski@yahoo.com>
2022-04-25 12:38:37 +02:00

254 lines
4.6 KiB
Vue

<template>
<div
:class="{[$style.sticky]: true, [$style.clickable]: !isResizing}"
:style="styles"
@keydown.prevent
>
<resize
:isResizingEnabled="!readOnly"
:height="height"
:width="width"
:minHeight="minHeight"
:minWidth="minWidth"
:scale="scale"
:gridSize="gridSize"
@resizeend="onResizeEnd"
@resize="onResize"
@resizestart="onResizeStart"
>
<template>
<div
v-show="!editMode"
:class="$style.wrapper"
@dblclick.stop="onDoubleClick"
>
<n8n-markdown
theme="sticky"
:content="content"
:withMultiBreaks="true"
/>
</div>
<div
v-show="editMode"
@click.stop
@mousedown.stop
@mouseup.stop
@keydown.esc="onInputBlur"
@keydown.stop
@wheel.stop
class="sticky-textarea"
:class="{'full-height': !shouldShowFooter}"
>
<n8n-input
:value="content"
type="textarea"
:rows="5"
@blur="onInputBlur"
@input="onInput"
ref="input"
/>
</div>
<div v-if="editMode && shouldShowFooter" :class="$style.footer">
<n8n-text
size="xsmall"
aligh="right"
>
<span v-html="t('sticky.markdownHint')"></span>
</n8n-text>
</div>
</template>
</resize>
</div>
</template>
<script lang="ts">
import N8nInput from '../N8nInput';
import N8nMarkdown from '../N8nMarkdown';
import Resize from './Resize';
import N8nText from '../N8nText';
import Locale from '../../mixins/locale';
import mixins from 'vue-typed-mixins';
export default mixins(Locale).extend({
name: 'n8n-sticky',
props: {
content: {
type: String,
},
height: {
type: Number,
default: 180,
},
width: {
type: Number,
default: 240,
},
minHeight: {
type: Number,
default: 80,
},
minWidth: {
type: Number,
default: 150,
},
scale: {
type: Number,
default: 1,
},
gridSize: {
type: Number,
default: 20,
},
id: {
type: String,
default: '0',
},
defaultText: {
type: String,
},
editMode: {
type: Boolean,
default: false,
},
readOnly: {
type: Boolean,
default: false,
},
},
components: {
N8nInput,
N8nMarkdown,
Resize,
N8nText,
},
data() {
return {
isResizing: false,
};
},
computed: {
resHeight(): number {
if (this.height < this.minHeight) {
return this.minHeight;
}
return this.height;
},
resWidth(): number {
if (this.width < this.minWidth) {
return this.minWidth;
}
return this.width;
},
styles() {
return {
height: this.resHeight + 'px',
width: this.resWidth + 'px',
};
},
shouldShowFooter() {
return this.resHeight > 100 && this.resWidth > 155;
},
},
methods: {
onDoubleClick() {
if (!this.readOnly) {
this.$emit('edit', true);
}
},
onInputBlur(value) {
if (!this.isResizing) {
this.$emit('edit', false);
}
},
onInput(value: string) {
this.$emit('input', value);
},
onResize(values) {
this.$emit('resize', values);
},
onResizeEnd(resizeEnd) {
this.isResizing = false;
this.$emit('resizeend', resizeEnd);
},
onResizeStart() {
this.isResizing = true;
this.$emit('resizestart');
},
},
watch: {
editMode(newMode, prevMode) {
setTimeout(() => {
if (newMode && !prevMode && this.$refs.input && this.$refs.input.$refs && this.$refs.input.$refs.textarea) {
const textarea = this.$refs.input.$refs.textarea;
if (this.defaultText === this.content) {
textarea.select();
}
textarea.focus();
}
}, 100);
},
},
});
</script>
<style lang="scss" module>
.sticky {
position: absolute;
background-color: var(--color-sticky-default-background);
border: 1px solid var(--color-sticky-default-border);
border-radius: var(--border-radius-base);
}
.clickable {
cursor: pointer;
}
.wrapper {
width: 100%;
height: 100%;
position: absolute;
padding: var(--spacing-2xs) var(--spacing-xs) 0;
overflow: hidden;
&::after {
content: '';
width: 100%;
height: 24px;
left: 0;
bottom: 0;
position: absolute;
background: linear-gradient(180deg, var(--color-sticky-default-background), #fff5d600 0.01%, var(--color-sticky-default-background));
border-radius: var(--border-radius-base);
}
}
.footer {
padding: var(--spacing-5xs) var(--spacing-2xs) 0 var(--spacing-2xs);
display: flex;
justify-content: flex-end;
}
</style>
<style lang="scss">
.sticky-textarea {
height: calc(100% - var(--spacing-l));
padding: var(--spacing-2xs) var(--spacing-2xs) 0 var(--spacing-2xs);
cursor: default;
.el-textarea {
height: 100%;
.el-textarea__inner {
height: 100%;
resize: unset;
}
}
}
.full-height {
height: calc(100% - var(--spacing-2xs));
}
</style>