459 lines
12 KiB
Vue
459 lines
12 KiB
Vue
<template>
|
|
<div class="form-row form-group" :key="$attrs.key">
|
|
<vue-tribute class="tribute-container" :options="tributeOptions">
|
|
<textarea
|
|
@tribute-no-match="noMatchFound"
|
|
@tribute-replaced="textReplaced"
|
|
:ref="localFormElement.key"
|
|
class="form-control"
|
|
@focus="clearErrors"
|
|
@blur="validate"
|
|
@change="validate"
|
|
:placeholder="localFormElement.placeholder"
|
|
:id="localFormElement.key"
|
|
:name="localFormElement.key"
|
|
v-model="textValue"
|
|
cols="1"
|
|
rows="1"
|
|
>
|
|
</textarea>
|
|
|
|
<div class="dropdown-container">
|
|
<div class="dropdown six-dot-btn">
|
|
<button
|
|
class="btn"
|
|
type="button"
|
|
id="dropdownMenu1"
|
|
data-toggle="dropdown"
|
|
aria-haspopup="true"
|
|
aria-expanded="false"
|
|
>
|
|
<div>
|
|
<div
|
|
data-block-id="ab81c411-c572-47f3-8f30-4051d9050c47"
|
|
class="notion-selectable notion-text-block"
|
|
>
|
|
<div
|
|
role="button"
|
|
tabindex="-1"
|
|
aria-label="Drag"
|
|
class="svg-container"
|
|
>
|
|
<svg
|
|
role="graphics-symbol"
|
|
viewBox="0 0 10 10"
|
|
class="dragHandle"
|
|
style="
|
|
width: 14px;
|
|
height: 14px;
|
|
display: block;
|
|
fill: inherit;
|
|
flex-shrink: 0;
|
|
"
|
|
>
|
|
<path
|
|
d="M3,2 C2.44771525,2 2,1.55228475 2,1 C2,0.44771525 2.44771525,0 3,0 C3.55228475,0 4,0.44771525 4,1 C4,1.55228475 3.55228475,2 3,2 Z M3,6 C2.44771525,6 2,5.55228475 2,5 C2,4.44771525 2.44771525,4 3,4 C3.55228475,4 4,4.44771525 4,5 C4,5.55228475 3.55228475,6 3,6 Z M3,10 C2.44771525,10 2,9.55228475 2,9 C2,8.44771525 2.44771525,8 3,8 C3.55228475,8 4,8.44771525 4,9 C4,9.55228475 3.55228475,10 3,10 Z M7,2 C6.44771525,2 6,1.55228475 6,1 C6,0.44771525 6.44771525,0 7,0 C7.55228475,0 8,0.44771525 8,1 C8,1.55228475 7.55228475,2 7,2 Z M7,6 C6.44771525,6 6,5.55228475 6,5 C6,4.44771525 6.44771525,4 7,4 C7.55228475,4 8,4.44771525 8,5 C8,5.55228475 7.55228475,6 7,6 Z M7,10 C6.44771525,10 6,9.55228475 6,9 C6,8.44771525 6.44771525,8 7,8 C7.55228475,8 8,8.44771525 8,9 C8,9.55228475 7.55228475,10 7,10 Z"
|
|
></path>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</button>
|
|
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
|
<notion-six-dot-component></notion-six-dot-component>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="dropdown plus-btn">
|
|
<button
|
|
class="btn"
|
|
type="button"
|
|
id="dropdownMenu2"
|
|
data-toggle="dropdown"
|
|
aria-haspopup="true"
|
|
aria-expanded="false"
|
|
>
|
|
<div
|
|
role="button"
|
|
tabindex="-1"
|
|
aria-label="Click to add below. Alt-click to add a block above"
|
|
>
|
|
<svg
|
|
role="graphics-symbol"
|
|
viewBox="0 0 16 16"
|
|
class="plus"
|
|
style="
|
|
width: 16px;
|
|
height: 100%;
|
|
display: block;
|
|
fill: inherit;
|
|
flex-shrink: 0;
|
|
"
|
|
>
|
|
<path
|
|
d="M7.977 14.963c.407 0 .747-.324.747-.723V8.72h5.362c.399 0 .74-.34.74-.747a.746.746 0 00-.74-.738H8.724V1.706c0-.398-.34-.722-.747-.722a.732.732 0 00-.739.722v5.529h-5.37a.746.746 0 00-.74.738c0 .407.341.747.74.747h5.37v5.52c0 .399.332.723.739.723z"
|
|
></path>
|
|
</svg>
|
|
</div>
|
|
</button>
|
|
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
|
|
<notion-plus-component></notion-plus-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</vue-tribute>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import formBuilderMixin from "~/extensions/formBuilderExtension";
|
|
|
|
import VueTribute from "vue-tribute";
|
|
import apis from "~/apis/borhanApi.js";
|
|
|
|
export default {
|
|
props: {
|
|
enableSuggestion: {
|
|
default: false,
|
|
},
|
|
contextMenu: {
|
|
default() {
|
|
return [];
|
|
},
|
|
},
|
|
},
|
|
extends: formBuilderMixin,
|
|
|
|
data() {
|
|
return {
|
|
types: [
|
|
{
|
|
id: "1",
|
|
title: "javascript",
|
|
},
|
|
{
|
|
id: "2",
|
|
title: "PHP",
|
|
},
|
|
{
|
|
id: "3",
|
|
title: "SpareQL",
|
|
},
|
|
{
|
|
id: "4",
|
|
title: "Paython",
|
|
},
|
|
{
|
|
id: "5",
|
|
title: "BASIC",
|
|
},
|
|
],
|
|
tributeOptions: {
|
|
// symbol or string that starts the lookup
|
|
trigger: "",
|
|
|
|
// element to target for @mentions
|
|
iframe: null,
|
|
|
|
// class added in the flyout menu for active item
|
|
selectClass: "highlight",
|
|
|
|
// class added to the menu container
|
|
containerClass: "tribute-container",
|
|
|
|
// class added to each list item
|
|
itemClass: "my-tribute-class",
|
|
|
|
// function called on select that returns the content to insert
|
|
selectTemplate: function (item) {
|
|
return item.original.value;
|
|
// return "@" + item.original.value;
|
|
},
|
|
|
|
// template for displaying item in menu
|
|
menuItemTemplate: function (item) {
|
|
return item.string;
|
|
},
|
|
|
|
// template for when no match is found (optional),
|
|
// If no template is provided, menu is hidden.
|
|
noMatchTemplate:
|
|
'<span class="no-result">مورد مشابهی ثبت نشده است.</span>',
|
|
|
|
// specify an alternative parent container for the menu
|
|
// container must be a positioned element for the menu to appear correctly ie. `position: relative;`
|
|
// default container is the body
|
|
menuContainer: document.body,
|
|
|
|
// column to search against in the object (accepts function or string)
|
|
lookup: "key",
|
|
|
|
// column that contains the content to insert by default
|
|
fillAttr: "value",
|
|
|
|
// REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
|
|
values: [
|
|
{
|
|
key: "سلام",
|
|
value: "سلام",
|
|
},
|
|
{
|
|
key: "باسلام",
|
|
value: "باسلام",
|
|
},
|
|
{
|
|
key: "علیک سلام",
|
|
value: "علیک سلام",
|
|
},
|
|
{
|
|
key: "بی سلام",
|
|
value: "بی سلام",
|
|
},
|
|
{
|
|
key: "صدتا سلام",
|
|
value: "صدتا سلام",
|
|
},
|
|
],
|
|
// values: ["سلام", "باسلام", "علیک سلام", "بی سلام", "صدتا سلام"],
|
|
// values: (text, cb) => {
|
|
// this.remoteSearch(text, (items) => cb(items));
|
|
// },
|
|
// When your values function is async, an optional loading template to show
|
|
loadingItemTemplate: null,
|
|
|
|
// specify whether a space is required before the trigger string
|
|
requireLeadingSpace: true,
|
|
|
|
// specify whether a space is allowed in the middle of mentions
|
|
allowSpaces: true,
|
|
|
|
// optionally specify a custom suffix for the replace text
|
|
// (defaults to empty space if undefined)
|
|
// replaceTextSuffix: "",
|
|
|
|
// specify whether the menu should be positioned. Set to false and use in conjuction with menuContainer to create an inline menu
|
|
// (defaults to true)
|
|
positionMenu: true,
|
|
|
|
// when the spacebar is hit, select the current match
|
|
spaceSelectsMatch: false,
|
|
|
|
// turn tribute into an autocomplete
|
|
autocompleteMode: true,
|
|
|
|
// Customize the elements used to wrap matched strings within the results list
|
|
// defaults to <span></span> if undefined
|
|
searchOpts: {
|
|
pre: "<span>",
|
|
post: "</span>",
|
|
skip: false, // true will skip local search, useful if doing server-side search
|
|
},
|
|
|
|
// Limits the number of items in the menu
|
|
menuItemLimit: 25,
|
|
|
|
// specify the minimum number of characters that must be typed before menu appears
|
|
menuShowMinLength: 0,
|
|
},
|
|
httpService: undefined,
|
|
};
|
|
},
|
|
mounted() {
|
|
this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
|
|
},
|
|
methods: {
|
|
limitText(count) {
|
|
return `و ${count} کاربر دیگر`;
|
|
},
|
|
noMatchFound(args) {
|
|
},
|
|
textReplaced(args) {
|
|
},
|
|
methodName(action, index = 0) {
|
|
try {
|
|
this[action](index);
|
|
} catch (err) {
|
|
this.$emit(action, index);
|
|
}
|
|
},
|
|
remoteSearch(input, callback) {
|
|
|
|
return this.httpService
|
|
.getRequest(apis.concept.annotations.read + "?ontology_id=" + input)
|
|
.then((res) => {
|
|
callback(res.data);
|
|
})
|
|
.catch((e) => {
|
|
callback([]);
|
|
})
|
|
.finally(() => {
|
|
this.fetchingData = false;
|
|
});
|
|
},
|
|
},
|
|
|
|
|
|
};
|
|
</script>
|
|
|
|
<!-- #region tribute -->
|
|
<style>
|
|
.tribute-container {
|
|
flex: 1 1 auto;
|
|
position: relative;
|
|
/* width: 100%; */
|
|
/* max-width: 100%; */
|
|
/* margin-top: 4px; */
|
|
/* margin-bottom: 4px; */
|
|
/* background-color: #fff; */
|
|
|
|
ul {
|
|
margin: 0;
|
|
margin-top: 2px;
|
|
padding: 0;
|
|
list-style: none;
|
|
/* background: #efefef; */
|
|
li {
|
|
padding: 0.5em 1em;
|
|
cursor: pointer;
|
|
|
|
&.highlight {
|
|
/* background: #ddd; */
|
|
}
|
|
|
|
&.no-match {
|
|
cursor: default;
|
|
}
|
|
|
|
span {
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
}
|
|
.menu-highlighted {
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
.form-group {
|
|
&:hover {
|
|
.ta-header,
|
|
.ta-options {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
transition: opacity 300ms ease-in 0s;
|
|
}
|
|
}
|
|
|
|
&.active,
|
|
&:active {
|
|
.ta-header,
|
|
.ta-options {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
transition: opacity 300ms ease-in 0s;
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
<!-- #endregion tribute -->
|
|
|
|
<style lang="scss" scoped>
|
|
.dropdown-container {
|
|
// user-select: none;
|
|
transition: background 20ms ease-in 0s;
|
|
// cursor: -webkit-grab;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
fill: rgba(55, 53, 47, 0.35);
|
|
position: absolute;
|
|
top: 3px;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 4px;
|
|
// pointer-events: auto;
|
|
right: -2.5em;
|
|
top: 1em;
|
|
|
|
.dropdown {
|
|
.dropdown-menu {
|
|
padding: 0;
|
|
border: none;
|
|
border-radius: 0.25rem;
|
|
text-align: inherit;
|
|
}
|
|
|
|
&.show {
|
|
.notion-text-block {
|
|
.svg-container {
|
|
// user-select: none;
|
|
// transition: background 20ms ease-in 0s;
|
|
// cursor: grab;
|
|
// display: flex;
|
|
// align-items: center;
|
|
// justify-content: center;
|
|
// width: 18px;
|
|
// height: 24px;
|
|
// border-radius: 4px;
|
|
fill: rgba(55, 53, 47, 0.35);
|
|
background: rgba(55, 53, 47, 0.08);
|
|
}
|
|
}
|
|
}
|
|
|
|
.notion-text-block {
|
|
.svg-container {
|
|
// user-select: none;
|
|
// transition: background 20ms ease-in 0s;
|
|
// cursor: grab;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 18px;
|
|
height: 24px;
|
|
border-radius: 4px;
|
|
// fill: rgba(55, 53, 47, 0.35);
|
|
// background: rgba(55, 53, 47, 0.08);
|
|
}
|
|
}
|
|
|
|
&.plus-btn {
|
|
// right: -44px;
|
|
|
|
.btn {
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
&.six-dot-btn {
|
|
// right: -22px;
|
|
.btn {
|
|
padding: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.form-control {
|
|
// flex-grow: 1;
|
|
// flex-shrink: 1;
|
|
// tab-size: 2;
|
|
padding: 1em;
|
|
min-height: 1em;
|
|
color: rgb(55, 53, 47);
|
|
white-space: pre;
|
|
|
|
border-radius: 4px;
|
|
// position: relative;
|
|
background: #fff;
|
|
min-width: 0px;
|
|
width: 100%;
|
|
resize: none;
|
|
border-color: transparent;
|
|
}
|
|
|
|
.main-page__content .form-builder div input {
|
|
border-color: transparent !important;
|
|
}
|
|
</style>
|