Modify addresses

This commit is contained in:
mustafa-rezae 2025-02-26 11:23:07 +03:30
parent 28bd8de77a
commit e9a34c2e6d
45 changed files with 1714 additions and 1262 deletions

Binary file not shown.

View File

@ -0,0 +1,9 @@
@font-face {
font-family: Takrim;
src: url("../fonts/Takrim.ttf");
src: url("../fonts/Takrim.ttf?#iefix") format("embedded-opentype"),
url("../fonts/Takrim.ttf") format("woff2"),
url("../fonts/Takrim.ttf") format("woff"),
url("../fonts/Takrim.ttf") format("truetype");
font-weight: normal;
}

View File

@ -79,7 +79,6 @@
<script>
import apis from "~/apis/permitApi";
// import { mapGetters, mapMutations, mapActions } from "vuex";
import { mapActions, mapState } from "pinia";
import { usePermitStore } from "~/stores/permitStore";

View File

@ -30,7 +30,7 @@
</div>
</template>
<script>
import newFormExtension from "@forms/extensions/newFormExtension";
import newFormExtension from "@extensions/newFormExtension";
export default {
extends: newFormExtension,

View File

@ -198,7 +198,7 @@
</div>
</template>
<script>
import newFormExtension from "@forms/extensions/newFormExtension";
import newFormExtension from "@extensions/newFormExtension";
export default {
extends: newFormExtension,
@ -279,7 +279,7 @@ export default {
),
NewTabForm: () =>
import(
"@forms/forms/NewTabForm.vue"
"@components/forms/NewTabForm.vue"
),
},
};

View File

@ -1,381 +0,0 @@
<template>
<div class="d-flex">
<label :for="localFormElement.key" :class="$attrs.labelClass ?? 'col-md-3'">{{ localFormElement.label }}:</label>
<div class="d-flex" :class="[$attrs.inputClass ?? ' col-md-9', { error: hasError }]">
<button type="button" class="btn btn-primary" @click="openModal('DataPropertyForm', 'فرم ایجاد خصوصیت ')">
انتخاب
</button>
<base-modal v-if="uploadForFirstTime" @canel="closeModal()" :showHeaderCloseButton="true" :modalTitle="modalTitle"
class="borhan-modal" modalSize="modal-lg" height="auto" maxHeight="40em" overflow="hidden" :showSaveButton="true"
:hasFooter="false">
<component :is="slotComponentName" :uploadForFirstTime="uploadForFirstTime" @saveAnnotation="sendTextValue"
:ontologyId="ontologyIdGetter" @close="closeModal()"></component>
</base-modal>
</div>
</div>
</template>
<script>
import formBuilderMixin from "@mixins/formBuilderMixin";
import HttpService from "@services/httpService";
import apis from "@apis/borhanApi.js";
import VueTribute from "vue-tribute";
import { mapGetters, mapMutations, mapActions } from "vuex";
export default {
mixins: [formBuilderMixin],
beforeMount() {
this.httpService = new HttpService();
},
mounted() {
this.multiSelectValue(this.formElement?.key);
},
data() {
return {
taskForm: "",
httpService: undefined,
templateValue: "",
options: [
{
title: "rational",
name: "rational",
},
{
title: "real",
name: "real",
},
{
title: "plainliteral",
name: "plainliteral",
},
{
title: "xmlliteral",
name: "xmlliteral",
},
{
title: "literal",
name: "literal",
},
{
title: "anyuri",
name: "anyuri",
},
{
title: "base64binary",
name: "base64binary",
},
{
title: "double",
name: "double",
},
{
title: "byte",
name: "byte",
},
{
title: "datetime",
name: "datetime",
},
{
title: "datetimestamp",
name: "datetimestamp",
},
{
title: "decimal",
name: "decimal",
},
{
title: "float",
name: "float",
},
{
title: "hexbinary",
name: "hexbinary",
},
{
title: "int",
name: "int",
},
{
title: "integer",
name: "integer",
},
{
title: "language",
name: "language",
},
{
title: "long",
name: "long",
},
{
title: "name",
name: "name",
},
{
title: "ncname",
name: "ncname",
},
{
title: "negativeinteger",
name: "negativeinteger",
},
{
title: "nmtoken",
name: "nmtoken",
},
{
title: "nonnegativeinteger",
name: "nonnegativeinteger",
},
{
title: "nonpositiveinteger",
name: "nonpositiveinteger",
},
{
title: "normalizedstring",
name: "normalizedstring",
},
{
title: "positiveinteger",
name: "positiveinteger",
},
{
title: "short",
name: "short",
},
{
title: "string",
name: "string",
},
{
title: "token",
name: "token",
},
{
title: "unsignedbyte",
name: "unsignedbyte",
},
{
title: "unsignedint",
name: "unsignedint",
},
{
title: "unsignedlong",
name: "unsignedlong",
},
{
title: "unsignedshort",
name: "unsignedshort",
},
],
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 mini",
// 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.title;
// return "@" + item.original.value;
},
// template for displaying item in menu
menuItemTemplate: function (item) {
return item.original.title;
},
// 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: "title",
// column that contains the content to insert by default
fillAttr: "title",
// REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
// values: [
// {
// key: null,
// value: "sghl",
// },
// ],
// 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 style="color:red">',
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,
},
uploadForFirstTime: false,
slotComponentName: null,
modalTitle: null,
};
},
computed: {
...mapGetters("borhan", ["ontologyIdGetter", "clickPointNameGetter"]),
},
methods: {
sendTextValue(event) {
// this.$emit("keydown", {
// event,
// });
let url = apis[this.$route.name].add;
url = url.replace("{{key}}", this.formElement.key);
let payload = {
ontology_id: this.ontologyIdGetter,
name1: this.clickPointNameGetter,
key: event.key,
lang: event?.lang,
type: event.datatype,
value: event.value,
prop: event.prop,
};
this.httpService
.postRequest(url, payload)
.then((res) => {
this.mySwalToast({
title: res.message ?? "اطلاعات با موفقیت ثبت شد.",
html: null,
icon: "success",
});
})
.catch((err) => { })
.finally(() => { });
},
closeModal() {
$("#base-modal").modal("hide");
setTimeout(() => {
this.uploadForFirstTime = false;
// this.createOntology();
}, 500);
},
openModal(componentName, title) {
this.uploadForFirstTime = true;
this.slotComponentName = componentName;
this.modalTitle = title;
setTimeout(() => {
$("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
}, 500);
},
multiSelectValue(item) {
this.httpService
.getRequest(
apis.property.update +
"?ontology_id=" +
this.ontologyIdGetter +
`&name1=${"dataproperty"}`
)
.then((res) => {
const list = res.data.Subobject_property;
const processedList = [];
list.forEach((element) => {
const newItem = { title: element.title, name: element.title }; // ایجاد یک شیء جدید با ویژگی title
processedList.push(newItem); // اضافه کردن شیء جدید به لیست
});
this.options = processedList;
});
},
},
components: {
VueTribute: () =>
import( "vue-tribute"),
Multiselect: () =>
import( "vue-multiselect"),
AnnotationFormAdd: () => import("@borhan/components/AnnotationFormAdd.vue"),
DataPropertyForm: () => import("@borhan/components/DataPropertyForm.vue"),
},
};
</script>
<style scoped lang="scss">
.form-control {
position: relative !important;
}
.button-input {
background-color: unset !important;
position: absolute !important;
left: 2px !important;
height: 100% !important;
border: 0;
display: flex;
justify-content: flex-end;
align-items: center;
}
</style>
<style lang="scss">
.class-search {
.multiselect__tags {
border: unset;
input {
border: unset !important;
}
}
}
</style>

View File

@ -6,7 +6,7 @@
>{{ localFormElement.label }}</label
>
<date-picker
<!-- <date-picker
v-if="localFormElement?.savetype == 'time'"
append-to="body"
:popover="{
@ -23,8 +23,8 @@
@input="$emit('oninput', $event)"
:placeholder="localFormElement.placeholder"
:type="'time'"
/>
<date-picker
/> -->
<!-- <date-picker
v-else-if="localFormElement?.subtype == 'simple'"
append-to="body"
:popover="{
@ -44,8 +44,8 @@
@input="$emit('oninput', $event)"
:placeholder="localFormElement.placeholder"
:type="'date'"
/>
<date-picker
/> -->
<!-- <date-picker
v-else
append-to="body"
:popover="{
@ -64,7 +64,7 @@
@input="$emit('oninput', $event)"
:placeholder="localFormElement.placeholder"
:type="'date'"
/>
/> -->
</div>
</template>
@ -107,7 +107,7 @@ export default {
},
components: {
// datePicker: VuePersianDatetimePicker,
datePicker: () => import("vue-persian-datetime-picker"),
// datePicker: () => import("vue-persian-datetime-picker"),
},
};
</script>

View File

@ -0,0 +1,86 @@
<template>
<div class="side-panel">
<div class="side-panel-header">
<h6 class="text-center">
مشخصات کامل مورد جاری
</h6>
</div>
<div class="border redios-castom px-3 py-2 ">
<div class="side-panel-content">
<form-builder
:previewMode="true"
:formElements="clonedFormElements"
:formData="selectedItem"
></form-builder>
</div>
<div class="d-flex justify-content-between">
<button-component
classes="d-inline-flex btn-default"
@click="closeFormShow"
buttonText=""
>
<span class="tavasi tavasi-Component-71--1"></span>
</button-component>
<button-component
classes="d-inline-flex btn-default"
@click="editItem"
buttonText=""
>
<i class="tavasi tavasi-Component-242--1"></i>
</button-component>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["selectedItem"],
emits: ["close-form-show", "edit-item"],
data() {
return {
clonedFormElements: {
items: [
{
key: "title",
label: "عنوان",
type: "label",
placeholder: "عنوان مختصری وارد کنید",
required: "0",
validation_regex: "",
validation_error: "",
multi_select: "0",
options: [],
value: null,
},
{
key: "comment",
label: "توضیح",
type: "label",
placeholder: "توضیح مختصری وارد کنید",
required: "0",
validation_regex: "",
validation_error: "",
multi_select: "0",
options: [],
value: null,
},
],
title: "فرم جزییات",
},
};
},
methods: {
closeFormShow() {
this.$emit("close-form-show");
},
editItem() {
this.$emit("edit-item", this.selectedItem);
},
},
};
</script>

View File

@ -18,7 +18,7 @@
</template>
<script>
import { mapGetters } from "vuex";
import { mapState } from "pinia";
import formBuilderMixin from "@mixins/formBuilderMixin";
import { codemirror } from "vue-codemirror";
@ -61,7 +61,7 @@ export default {
this.cmOptions.placeholder = this.localFormElement.placeholder;
},
computed: {
...mapGetters("entity", ["draftActiveStepGetter"]),
...mapState(entityStore, ["draftActiveStepGetter"]),
},
components: {
codemirror,

View File

@ -1,404 +0,0 @@
<template>
<div class="d-flex">
<label :for="localFormElement.key" :class="$attrs.labelClass ?? 'col-md-3'">{{ localFormElement.label }}:</label>
<div class="d-flex" :class="[$attrs.inputClass ?? ' col-md-9', { error: hasError }]">
<div class="col-md-5">
<multiselect class="class-search" track-by="id" label="title" placeholder=" انتخاب کنید... "
v-model="templateValue" :options="options" :searchable="true" :internal-search="false" :clear-on-select="false"
:close-on-select="true" :options-limit="300" :limit="3" :max-height="350" @search-change="asyncFind"
@select="forwardMessage" @close="resetFoundUsers">
</multiselect>
</div>
<div class="d-flex col-md-10">
<vue-tribute class="col-md-12 ps-0 pe-0" :options="tributeOptions">
<input class="label-1 form-control task-form-control task-title" :placeholder="localFormElement.placeholder"
:type="localFormElement.type" :id="localFormElement.key" :name="localFormElement.key" v-model="textValue"
@tribute-no-match="noMatchFound" @tribute-replaced="textReplaced" />
</vue-tribute>
<button type="button" class="btn btn-light button-input" :class="$attrs.buttonClass"
@click.prevent="sendTextValue" style="width: 4em">
<svg class="icon icon-Component-233--1">
<use xlink:href="#icon-Component-233--1"></use>
</svg>
</button>
</div>
<button type="button" class="btn btn-light" v-if="isUpdateitem" @click="handlerUpdate">
<svg class="icon icon-Component-294--1">
<use xlink:href="#icon-Component-294--1"></use>
</svg>
</button>
</div>
</div>
</template>
<script>
import formBuilderMixin from "@mixins/formBuilderMixin";
import HttpService from "@services/httpService";
import apis from "@apis/borhanApi.js";
import VueTribute from "vue-tribute";
import { mapGetters, mapMutations, mapActions } from "vuex";
export default {
mixins: [formBuilderMixin],
beforeMount() {
this.httpService = new HttpService();
},
mounted() {
this.multiSelectValue(this.formElement.key);
},
data() {
return {
taskForm: "",
httpService: undefined,
templateValue: "",
options: [
{
title: "rational",
name: "rational",
},
{
title: "real",
name: "real",
},
{
title: "plainliteral",
name: "plainliteral",
},
{
title: "xmlliteral",
name: "xmlliteral",
},
{
title: "literal",
name: "literal",
},
{
title: "anyuri",
name: "anyuri",
},
{
title: "base64binary",
name: "base64binary",
},
{
title: "double",
name: "double",
},
{
title: "byte",
name: "byte",
},
{
title: "datetime",
name: "datetime",
},
{
title: "datetimestamp",
name: "datetimestamp",
},
{
title: "decimal",
name: "decimal",
},
{
title: "float",
name: "float",
},
{
title: "hexbinary",
name: "hexbinary",
},
{
title: "int",
name: "int",
},
{
title: "integer",
name: "integer",
},
{
title: "language",
name: "language",
},
{
title: "long",
name: "long",
},
{
title: "name",
name: "name",
},
{
title: "ncname",
name: "ncname",
},
{
title: "negativeinteger",
name: "negativeinteger",
},
{
title: "nmtoken",
name: "nmtoken",
},
{
title: "nonnegativeinteger",
name: "nonnegativeinteger",
},
{
title: "nonpositiveinteger",
name: "nonpositiveinteger",
},
{
title: "normalizedstring",
name: "normalizedstring",
},
{
title: "positiveinteger",
name: "positiveinteger",
},
{
title: "short",
name: "short",
},
{
title: "string",
name: "string",
},
{
title: "token",
name: "token",
},
{
title: "unsignedbyte",
name: "unsignedbyte",
},
{
title: "unsignedint",
name: "unsignedint",
},
{
title: "unsignedlong",
name: "unsignedlong",
},
{
title: "unsignedshort",
name: "unsignedshort",
},
],
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 mini",
// 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.title;
// return "@" + item.original.value;
},
// template for displaying item in menu
menuItemTemplate: function (item) {
return item.original.title;
},
// 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: "title",
// column that contains the content to insert by default
fillAttr: "title",
// REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
// values: [
// {
// key: null,
// value: "sghl",
// },
// ],
// 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 style="color:red">',
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,
},
};
},
computed: {
...mapGetters("borhan", ["ontologyIdGetter", "clickPointNameGetter"]),
},
methods: {
asyncFind() { },
multiSelectValue(item) {
if (item == "objcet_property_assertions") {
this.httpService
.getRequest(
apis.property.update +
"?ontology_id=" +
this.ontologyIdGetter +
`&name1=${"objectproperty"}`
)
.then((res) => {
const list = res.data.Subobject_property;
const processedList = [];
list.forEach((element) => {
const newItem = { title: element.title, name: element.title }; // ایجاد یک شیء جدید با ویژگی title
processedList.push(newItem); // اضافه کردن شیء جدید به لیست
});
this.options = processedList;
});
}
},
forwardMessage(newTag) {
this.templateValue = newTag;
},
resetFoundUsers() { },
noMatchFound(args) {
console.info(args);
},
textReplaced(args) {
console.info(args);
},
remoteSearch(text, cb) {
let url = "";
if (this.formElement.key == "type") {
const queryParams = new URLSearchParams({
ontology_id: this.ontologyIdGetter,
search: text,
});
url = apis.class.autoComplate + "?" + queryParams;
} else {
const queryParams = new URLSearchParams({
ontology_id: this.ontologyIdGetter,
search: text,
});
url = apis[this.$route.name].autoComplate + "?" + queryParams;
}
// if (text == "") url = taskApi.workingHours.complitionAll;
this.httpService
.getRequest(url)
.then((response) => {
const list = response.data;
const processedList = [];
list.forEach((element) => {
const newItem = { title: element }; // ایجاد یک شیء جدید با ویژگی title
processedList.push(newItem); // اضافه کردن شیء جدید به لیست
});
cb(processedList);
})
.catch((error) => { })
.finally(() => { });
},
sendTextValue() {
this.$emit("keydown", {
text: this.textValue,
prop: this.templateValue.name,
key: this.keyValue,
isUpdate: this.isUpdateitem,
});
this.textValue = "";
},
handlerUpdate() {
this.textValue = "";
this.templateValue = "";
this.isUpdateitem = false;
},
},
components: {
VueTribute: () =>
import( "vue-tribute"),
Multiselect: () =>
import( "vue-multiselect"),
},
};
</script>
<style scoped lang="scss">
.form-control {
position: relative !important;
}
.button-input {
background-color: unset !important;
position: absolute !important;
left: 2px !important;
height: 100% !important;
border: 0;
display: flex;
justify-content: flex-end;
align-items: center;
}
</style>
<style lang="scss">
.class-search {
.multiselect__tags {
border: unset;
input {
border: unset !important;
}
}
}
</style>

View File

@ -1,216 +0,0 @@
<template>
<div class="d-flex">
<label :for="localFormElement.key" :class="$attrs.labelClass ?? 'col-md-3'">{{ localFormElement.label }}:</label>
<div class="d-flex" :class="[$attrs.inputClass ?? ' col-md-9', { error: hasError }]">
<vue-tribute class="col-md-12 ps-0 pe-0" :options="tributeOptions">
<input class="label-1 form-control task-form-control task-title" :placeholder="localFormElement.placeholder"
:type="localFormElement.type" :id="localFormElement.key" :name="localFormElement.key" v-model="textValue"
@tribute-no-match="noMatchFound" @tribute-replaced="textReplaced" />
</vue-tribute>
<button type="button" class="btn btn-light button-input" :class="$attrs.buttonClass" @click.prevent="sendTextValue"
style="width: 4em">
<svg class="icon icon-Component-233--1">
<use xlink:href="#icon-Component-233--1"></use>
</svg>
</button>
</div>
<button type="button" class="btn btn-light" v-if="isUpdateitem" @click="handlerUpdate">
<svg class="icon icon-Component-294--1">
<use xlink:href="#icon-Component-294--1"></use>
</svg>
</button>
</div>
</template>
<script>
import formBuilderMixin from "@mixins/formBuilderMixin";
import HttpService from "@services/httpService";
import apis from "@apis/borhanApi.js";
import VueTribute from "vue-tribute";
import { mapGetters, mapMutations, mapActions } from "vuex";
export default {
mixins: [formBuilderMixin],
beforeMount() {
this.httpService = new HttpService();
},
data() {
return {
taskForm: "",
httpService: undefined,
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 mini",
// 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.title;
// return "@" + item.original.value;
},
// template for displaying item in menu
menuItemTemplate: function (item) {
return item.original.title;
},
// 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: "title",
// column that contains the content to insert by default
fillAttr: "title",
// REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
// values: [
// {
// key: null,
// value: "sghl",
// },
// ],
// 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 style="color:red">',
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,
},
};
},
computed: {
...mapGetters("borhan", ["ontologyIdGetter", "clickPointNameGetter"]),
},
methods: {
noMatchFound(args) {
console.info(args);
},
textReplaced(args) {
console.info(args);
},
remoteSearch(text, cb) {
let url = "";
if (this.formElement.key == "type") {
const queryParams = new URLSearchParams({
ontology_id: this.ontologyIdGetter,
search: text,
});
url = apis.class.autoComplate + "?" + queryParams;
} else {
const queryParams = new URLSearchParams({
ontology_id: this.ontologyIdGetter,
search: text,
});
url = apis[this.$route.name].autoComplate + "?" + queryParams;
}
// if (text == "") url = taskApi.workingHours.complitionAll;
this.httpService
.getRequest(url)
.then((response) => {
const list = response.data;
const processedList = [];
list.forEach((element) => {
const newItem = { title: element }; // ایجاد یک شیء جدید با ویژگی title
processedList.push(newItem); // اضافه کردن شیء جدید به لیست
});
cb(processedList);
})
.catch((error) => { })
.finally(() => { });
},
sendTextValue() {
this.$emit("keydown", {
text: this.textValue,
key: this.keyValue,
isUpdate: this.isUpdateitem,
});
this.textValue = "";
},
handlerUpdate() {
this.textValue = "";
this.isUpdateitem = false;
},
},
components: {
VueTribute: () =>
import( "vue-tribute"),
},
};
</script>
<style scoped lang="scss">
.form-control {
position: relative !important;
}
.button-input {
background-color: unset !important;
position: absolute !important;
left: 2px !important;
height: 100% !important;
border: 0;
display: flex;
justify-content: flex-end;
align-items: center;
}
</style>

View File

@ -0,0 +1,183 @@
<template>
<div class="side-panel">
<div class="side-panel-header">
<h6 class="text-center">
افزودن آیتم جدید
</h6>
</div>
<div class="redios-castom px-3 py-2 ">
<div class="side-panel-content">
<form @submit.prevent="saveNewItemForm()" class="text__14">
<form-builder
ref="newFormItemBuilder"
:formElements="formElement"
:formData="formData"
></form-builder>
<div class="mb-3">
<button-component
type="submit"
classes="btn-outline-primary mx-3"
buttonText="افزودن"
:buttonLoading="buttonLoading"
></button-component>
<button-component
classes="btn-danger"
buttonText="انصراف"
:buttonLoading="buttonLoading"
@click="closeNewFormItem"
></button-component>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
emits: ["close-new-form-item","add-item-content"],
props: {
editFormData: {
default() {
return {};
},
},
},
watch: {
editFormData: {
handler(newVal) {
this.formData = newVal;
},
},
},
mounted(){
this.formData = this.editFormData;
},
data() {
return {
buttonLoading: false,
formData: {
name: "",
key: "",
placeholder: "",
type: "",
},
formElement: {
title: "مشخصات اصلی",
items: [
{
key: "label",
label: "عنوان",
type: "string",
placeholder: "عنوان را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "key",
label: "کلیدواژه",
type: "string",
placeholder: "کلیدواژه را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "placeholder",
label: "راهنما",
type: "string",
placeholder: "راهنمای اولیه مختصر را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "value",
label: "مقدار",
type: "string",
placeholder: "مقدار را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "type",
label: "نوع",
type: "select",
placeholder: "نوع را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [
{
title: "صوتی",
value: "sound",
},
{
title: "فیلم",
value: "video",
},
{
title: "تصویر",
value: "img",
},
{
title: "عبارت(نمایشی)",
value: "label",
},
{
title: "متن",
value: "textarea",
},
{
title: "انتخابی",
value: "select",
},
{
title: "متن کوتاه",
value: "string",
},
],
},
],
},
};
},
methods: {
closeNewFormItem() {
this.$emit("close-new-form-item");
},
saveNewItemForm() {
const formData = this.$refs.newFormItemBuilder.localFormData;
this.$emit("add-item-content", formData);
},
resetForm() {
this.formData = {
name: "",
key: "",
placeholder: "",
type: "",
};
},
},
};
</script>
<style lang="scss"></style>

View File

@ -0,0 +1,85 @@
<template>
<div class="side-panel">
<form @submit.prevent="saveNewTab()" class="text__14">
<form-builder
ref="newTabBuilder"
:formElements="formElement"
:formData="formData"
></form-builder>
<div class="mb-3">
<button-component
type="submit"
classes="btn-outline-primary mx-3"
buttonText="افزودن"
:buttonLoading="buttonLoading"
></button-component>
<button-component
classes="btn-danger"
buttonText="انصراف"
:buttonLoading="buttonLoading"
@click="closeNewFormItem"
></button-component>
</div>
</form>
</div>
</template>
<script>
export default {
emits: ["close-new-form-item", "add-item-content"],
data() {
return {
buttonLoading: false,
formData: {
title: null,
comment: null,
type: 1,
meta: null,
table_columns: null,
},
formElement: {
title: "بخش جدید",
items: [
{
key: "title",
label: "عنوان",
type: "string",
placeholder: "عنوان را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "comment",
label: "توضیحات",
type: "textarea",
placeholder: "توضیحات را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
],
},
};
},
methods: {
closeNewFormItem() {
this.$emit("close-new-form-item");
},
saveNewTab() {
const formData = this.$refs.newTabBuilder.localFormData;
this.$emit("add-item-content", formData);
},
},
};
</script>
<style lang="scss"></style>

View File

@ -98,8 +98,10 @@
<script>
import repoApi from "@apis/repoApi";
import { mapGetters, mapMutations } from "vuex";
import { mapState } from "pinia";
import HttpService from "@services/httpService";
import { useEntityStore } from "~/systems/search_ui/stores/entityStore";
import { useCommonStore } from "~/systems/search_ui/stores/useCommonStore";
/**
* @vue-data {Object} [listUpdatedText = {}] - متنهای بهروزشده در لیست.
* @vue-data {undefined} [httpService = undefined] - سرویس HTTP برای درخواستها.
@ -158,11 +160,11 @@ export default {
};
},
computed: {
...mapGetters("entity", [
...mapGetters(useEntityStore, [
// "selectedItemEntityGetter",
"activeTabGetter",
]),
...mapGetters(["userPermisionGetter", "currentUser"]),
...mapGetters(useCommonStore,["userPermisionGetter", "currentUser"]),
},
methods: {
// ...mapMutations("entity", ["SET_ITEM_ENTITY"]),

View File

@ -0,0 +1,79 @@
<template>
<div class="position-relative ms-5">
<my-table
height="auto"
maxHeight="calc(100vh - 15em)"
:isSortable="true"
:isDraggable="true"
:hasSearch="false"
:hasPagination="false"
:fetchingData="fetchingData"
:items="localMainFormElements[currentTab]?.items"
:tableColumns="tableColumns"
:tableActions="formTableActions"
@delete-table-item="deleteItem"
@edit-table-item="editNewFormItem"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<button-component
classes="d-inline-flex add-new-form-item"
@click="openNewFormItem"
buttonText=""
>
<span class="tavasi tavasi-Component-220--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
</template>
<script>
import newFormExtension from "@extensions/newFormExtension";
export default {
extends: newFormExtension,
props: ["newFormItem", "formTitleData"],
mounted() {
const form = [
{
title: "فرم ساده",
items: [],
active: true,
},
];
this.localMainFormElements = this.formTitleData.meta ?? form;
},
data() {
return {
localMainFormElements: [
{
title: "فرم ساده",
items: [],
active: true,
},
],
};
},
components: {
LabelComponent: () =>
import(
"@components/forms/LabelComponent.vue"
),
},
};
</script>
<style scoped lang="scss">
.add-new-form-item {
position: absolute;
left: -3em;
bottom: 0;
}
</style>

View File

@ -0,0 +1,337 @@
<template>
<div>
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li
v-for="(groupItem, index) in localMainFormElements"
:key="index"
@click="setTab(index)"
class="nav-item"
role="presentation"
>
<a
class="nav-link position-relative ms-3"
id="home-tab"
data-bs-toggle="tab"
:href="'#' + groupItem.key"
role="tab"
:aria-controls="groupItem.key"
aria-selected="true"
:class="{ active: groupItem.active ?? false }"
>{{ groupItem.title }}
<button-component
classes="d-inline-flex tab-remove-btn"
@click="removeTab(index)"
buttonText=""
>
<span class="tavasi tavasi-Component-21--1"></span>
</button-component>
<button-component
classes="d-inline-flex tab-edit-btn"
@click="openEditTabFormModal(index)"
buttonText=""
title="ویرایش"
>
<span class="tavasi tavasi-Component-242--1"></span>
</button-component>
</a>
</li>
<li class="nav-item" role="presentation">
<!-- add button -->
<button-component
classes="nav-link d-inline-flex"
@click="openNewTabFormModal()"
buttonText="بخش جدید"
>
<span class="tavasi tavasi-Component-220--1 ms-1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</li>
</ul>
<div
class="tab-content"
id="myTabContent"
v-if="localMainFormElements?.length"
>
<div
class="tab-pane fade show active p-3"
id="home"
role="tabpanel"
aria-labelledby="home-tab"
>
<div
v-if="localMainFormElements[currentTab]?.hasChildren"
class="accordion"
id="accordionExample"
>
<div
v-for="(innerGroupItem, j) in localMainFormElements[currentTab]
?.items"
:key="j"
class="card"
>
<div class="card-header" :id="'heading' + j">
<h2 class="mb-0 d-flex">
<!-- حذف تب داخلی یا فرزند -->
<button-component
classes="d-inline-flex p-0"
@click="removeChildTab(j)"
buttonText=""
title="حذف"
>
<span class="tavasi tavasi-Component-295--1"></span>
</button-component>
<!-- باز کردن مودال ویرایش تب داخلی یا فرزند -->
<button-component
classes="d-inline-flex p-0"
@click="openChildTabEditModal(j)"
buttonText=""
title="ویرایش"
>
<span class="tavasi tavasi-Component-242--1"></span>
</button-component>
<button
class="btn btn-link btn-block has-indicator"
type="button"
data-bs-toggle="collapse"
:data-bs-target="'#collapse' + j"
:aria-expanded="innerGroupItem.active ?? false"
:aria-controls="'collapse' + j"
:class="{ active: innerGroupItem.active ?? false }"
>
{{ innerGroupItem.title }}
</button>
</h2>
</div>
<div
:id="'collapse' + j"
class="collapse"
:class="{ show: innerGroupItem.active ?? false }"
:aria-labelledby="'heading' + j"
data-parent="#accordionExample"
>
<div class="card-body">
<div class="position-relative ms-5">
<my-table
height="auto"
maxHeight="calc(100vh - 15em)"
:isSortable="true"
:isDraggable="true"
:hasSearch="false"
:hasPagination="false"
:fetchingData="fetchingData"
:items="localMainFormElements[currentTab]?.items[j]?.items"
:tableColumns="tableColumns"
:tableActions="formTableActions"
@delete-table-item="deleteChildItem($event, j)"
@edit-table-item="childEditNewFormItem($event, j)"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<button-component
classes="d-inline-flex add-new-form-item"
@click="openChildNewFormItem(j)"
buttonText=""
>
<span class="tavasi tavasi-Component-220--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
</div>
</div>
</div>
</div>
<div v-else class="position-relative ms-5">
<my-table
height="auto"
maxHeight="calc(100vh - 15em)"
:isSortable="true"
:isDraggable="true"
:hasSearch="false"
:hasPagination="false"
:fetchingData="fetchingData"
:items="localMainFormElements[currentTab]?.items"
:tableColumns="tableColumns"
:tableActions="formTableActions"
@delete-table-item="deleteItem"
@edit-table-item="editNewFormItem"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<button-component
classes="d-inline-flex add-new-form-item"
@click="openNewFormItem"
buttonText=""
>
<span class="tavasi tavasi-Component-220--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
</div>
</div>
<!-- new tab modal -->
<base-modal
v-if="showNewTabFormModal"
modalSize="modal-md"
modalTitle="فرم جدید"
@close="closeNewTabFormModal"
@save="addTab"
>
<form-builder
ref="tabFormBuilder"
:formElements="formTabElement"
:formData="formTabData"
></form-builder>
</base-modal>
</div>
</template>
<script>
import newFormExtension from "@extensions/newFormExtension";
export default {
extends: newFormExtension,
props: ["newFormItem", "formTitleData"],
mounted() {
this.localMainFormElements = this.formTitleData.meta ?? [];
if (this.localMainFormElements && this.localMainFormElements[0])
this.localMainFormElements[0].active = true;
},
data() {
return {
prevActiveTabIndex: undefined,
localMainFormElements: [],
showNewTabFormModal: false,
// form title elemnets and data.
formTabData: {
title: null,
},
formTabElement: {
title: "",
items: [
{
key: "parent",
label: "والد",
type: "select",
placeholder: "والد را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "title",
label: "عنوان",
type: "string",
placeholder: "عنوان را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
{
key: "key",
label: "کلیدواژه",
type: "string",
placeholder: "کلیدواژه را وارد کنید",
required: "1",
validation_regex: "{3-100}",
validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
multi_select: "0",
options: [],
},
// {
// key: "newButtonText",
// label: "عنوان دکمه ایجاد",
// type: "string",
// placeholder: "عنوان دکمه ایجاد را وارد کنید",
// required: "1",
// validation_regex: "{3-100}",
// validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
// multi_select: "0",
// options: [],
// },
],
},
};
},
components: {
LabelComponent: () =>
import(
"@components/forms/LabelComponent.vue"
),
NewTabForm: () =>
import(
"@forms/forms/NewTabForm.vue"
),
},
};
</script>
<style scoped lang="scss">
.tab-remove-btn {
position: absolute;
left: -0.5em;
top: -0.5em;
background-color: #fff;
justify-content: center;
align-items: center;
padding: 0;
span {
color: var(--danger);
}
&:hover {
background-color: var(--danger);
span {
color: #fff;
}
}
}
.tab-edit-btn {
position: absolute;
left: -0.5em;
bottom: 0em;
background-color: #fff;
justify-content: center;
align-items: center;
padding: 0;
&:hover {
background-color: #ddd;
span {
color: #fff;
}
}
}
.add-new-form-item {
position: absolute;
left: -3em;
bottom: 0;
}
</style>
<style>
.accordion .card .card-body .btn::after {
content: none;
}
</style>

View File

@ -0,0 +1,106 @@
<template>
<div class="side-panel">
<div class="side-panel-header">
<h6>
انتخاب ستونها در حالت نمایش فهرستی(جدولی)
</h6>
</div>
<div class="side-panel-content">
<form @submit.prevent="saveColumn">
<div class="row form-group">
<label for="key" class="col-md-3">کلیدواژه: </label>
<select
class="form-control col-md-9"
placeholder="کلیدواژه"
type="key"
id="key"
name="key"
v-model="localFormElement.key"
>
<option
v-for="option in selectedForm.flatedItems"
:value="option.key"
>{{ option.label }}({{ option.key }})</option
>
</select>
</div>
<div class="row form-group">
<label for="title" class="col-md-3">عنوان: </label>
<input
class="form-control col-md-9"
placeholder="عنوان"
type="title"
id="title"
name="title"
v-model="localFormElement.title"
/>
</div>
<div class="row form-group">
<label for="width" class="col-md-3">وزن: </label>
<input
class="form-control col-md-9"
placeholder="وزن"
type="width"
id="width"
name="width"
v-model="localFormElement.width"
/>
</div>
<div class="row form-group">
<div class="d-flex justify-content-between">
<button-component
classes="btn btn-primary d-inline-flex btn-default"
buttonText="افزودن"
type="submit"
>
</button-component>
<button-component
classes="d-inline-flex btn-danger"
@click="closeFormShow"
buttonText="بستن"
>
<!-- <span class="tavasi tavasi-Component-71--1"></span> -->
</button-component>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
export default {
props: ["selectedItem", "selectedForm"],
emits: ["close-form-show", "update-column"],
data() {
return {
displayMode:'table',
localFormElement: {
title: null,
key: null,
width: 1,
},
};
},
mounted() {
this.localFormElement = structuredClone(this.selectedItem);
},
watch: {
selectedItem(newval) {
this.localFormElement = structuredClone(newval);
},
},
methods: {
closeFormShow() {
this.$emit("close-form-show");
},
saveColumn() {
const clonedLocalFormElement = structuredClone(this.localFormElement);
this.$emit("update-column", clonedLocalFormElement);
},
},
};
</script>

View File

@ -102,7 +102,6 @@
<script>
import HttpService from "@services/httpService";
import repoApi from "@apis/repoApi";
import { mapMutations, mapGetters } from "vuex";
export default {
props: {

View File

@ -54,6 +54,7 @@
<script>
import { mapState } from "pinia";
import { useEntityStore } from "~/systems/search_ui/stores/entityStore";
export default {
props: {
@ -70,7 +71,7 @@ export default {
},
},
computed: {
...mapState("entity", ["vuexEntityGetter"]),
...mapState(useEntityStore, ["vuexEntityGetter"]),
},
methods: {
normalPathKey(title = "") {

View File

@ -36,7 +36,7 @@
</template>
<script>
import {mapActions} from 'vuex';
import {mapActions} from 'pinia';
import { useCommonStore } from "~/stores/commonStore";
export default {

View File

@ -0,0 +1,440 @@
/* Be aware that component extension is not as classes inheritance.
In this case, Vue merges both the parent and child component options creating a new mixed object.
For the case of the mounted and destroyed hook, both the parents and childrens are kept and they
will be called in inheritance order, from parent to children.
https://vueschool.io/articles/vuejs-tutorials/reusing-logic-in-vue-components/
*/
/* hooks order
1) extension
2) mixins
3) component
*/
import formTableActions from "@json/formTableActions";
export default {
data() {
return {
addToChildren: false,
editChildTab: false,
parentRowItemIndex: 0,
childRowItemIndex: 0,
childRowItem: {},
parentRowItem: {},
tabIndex: undefined,
childTabIndex: undefined,
fetchingData: false,
tableColumns: [
{
isLink: true,
key: "label",
title: "عنوان",
width: "1",
},
{
key: "key",
title: "کلید",
width: "1",
},
{
key: "placeholder",
title: "راهنما",
width: "3",
},
{
key: "value",
title: "مقدار",
width: "1",
},
{
key: "type",
title: "نوع",
width: "1",
},
],
formTableActions: formTableActions,
localFormData: {},
currentTab: 0,
buttonLoading: false,
};
},
methods: {
onLinkedTitleClick({ rowItem, tableColumn, index }) {
this.editNewFormItem(index);
},
/*
summary: change the sort of form items(elements)
description: changing the sort of the form items
in the table by drag and drop them.
@param {Event} Sortable sort event.
@param {newIndex} String dropped into index.
@param {oldIndex} String dragged from index.
@return void.
*/
onSort({ newIndex, oldIndex }) {
const tempItem =
this.localMainFormElements[this.currentTab].items[newIndex];
this.localMainFormElements[this.currentTab].items[newIndex] =
this.localMainFormElements[this.currentTab].items[oldIndex];
this.localMainFormElements[this.currentTab].items[oldIndex] = tempItem;
},
openNewTabFormModal() {
this.showNewTabFormModal = true;
this.tabIndex = undefined;
const options = [
{
title: "بدون والد",
value: null,
},
];
this.localMainFormElements.forEach((element) => {
options.push({ title: element.title, value: element.title });
});
this.formTabElement.items[0].options = options;
setTimeout(() => {
$("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
}, 500);
},
openEditTabFormModal(index) {
this.editChildTab = false;
this.tabIndex = index;
this.childTabIndex = undefined;
const options = [
{
title: "بدون والد",
value: null,
},
];
this.localMainFormElements.forEach((element) => {
options.push({ title: element.title, value: element.title });
});
this.formTabElement.items[0].options = options;
this.formTabData = this.localMainFormElements[index];
this.showNewTabFormModal = true;
setTimeout(() => {
$("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
}, 500);
},
openChildTabEditModal(childIndex) {
this.editChildTab = true;
this.tabIndex = undefined;
this.childTabIndex = childIndex;
const options = [
{
title: "بدون والد",
value: null,
},
];
this.localMainFormElements.forEach((element) => {
options.push({ title: element.title, value: element.title });
});
this.formTabElement.items[0].options = options;
this.formTabData =
this.localMainFormElements[this.currentTab].items[childIndex];
this.showNewTabFormModal = true;
setTimeout(() => {
$("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
}, 500);
},
closeNewTabFormModal() {
$("#base-modal").modal("hide");
setTimeout(() => {
this.showNewTabFormModal = false;
}, 500);
},
addTab() {
if (this.editChildTab) this.addChildTab();
else this.addParentTab();
this.closeNewTabFormModal();
},
addParentTab() {
const tab = this.$refs.tabFormBuilder.localFormData;
if (tab.parent) {
const tabItem = this.localMainFormElements.find(
(item) => item.title == tab.parent
);
tabItem.active = true;
if (tabItem) {
tabItem.hasChildren = true;
tabItem.items.push({
parent: tab.parent,
key: tab.key,
title: tab.title,
active: true,
items: [],
});
}
} else {
if (this.tabIndex == undefined) {
this.localMainFormElements.push({
key: tab.key,
title: tab.title,
active: true,
items: [],
});
this.setTab(this.localMainFormElements?.length - 1);
} else {
this.localMainFormElements[this.tabIndex].title = tab.title;
this.localMainFormElements[this.tabIndex].key = tab.key;
}
}
},
addChildTab() {
const tab = this.$refs.tabFormBuilder.localFormData;
const tabItem =
this.localMainFormElements[this.currentTab].items[this.childTabIndex];
if (tabItem) {
tabItem.parent = tab.parent;
tabItem.title = tab.title;
tabItem.key = tab.key;
tabItem.newButtonText = tab.newButtonText ?? tab.title;
}
},
setTab(index) {
if (this.localMainFormElements[index].hasChildren) {
this.addToChildren = true;
} else {
this.addToChildren = false;
}
if (this.prevActiveTabIndex != undefined)
this.localMainFormElements[this.prevActiveTabIndex].active = false;
this.prevActiveTabIndex = this.currentTab = index;
},
removeParentTab(index) {
this.mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
if (result.isConfirmed) {
this.localMainFormElements.splice(index, 1);
}
});
},
removeChildTab(childIndex) {
this.mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
if (result.isConfirmed) {
this.localMainFormElements[this.currentTab].items.splice(
childIndex,
1
);
}
});
},
// addFormItemToFormElements(newFormItem) {
// if (this.localMainFormElements[this.currentTab].items?.length == 0)
// this.localMainFormElements[this.currentTab].items.push(newFormItem);
// else {
// }
// },
addFormItemToFormElements(updatedColumn) {
if (this.addToChildren) this.addItemToChildren(updatedColumn);
else this.addItemToParent(updatedColumn);
},
addItemToChildren(updatedColumn) {
if (this.childRowItemIndex)
this.$set(
this.localMainFormElements[this.currentTab].items[
this.parentRowItemIndex
].items,
this.childRowItemIndex,
updatedColumn
);
else {
// find new item in the forms table columns items.
// if exist => continue
// else catch block executs and create new table columns.
try {
const res = this.localMainFormElements[this.currentTab].items[
this.parentRowItemIndex
].items.filter((item) => item.key == updatedColumn.key);
if (res.length)
this.mySwalToast({
title: "ستونی با چنین مشخصاتی قبلا ایجاد شده است.",
html: null,
icon: "error",
});
else {
this.localMainFormElements[this.currentTab].items[
this.parentRowItemIndex
].items.push(updatedColumn);
}
} catch (msg) {
this.localMainFormElements[this.currentTab].items[
this.parentRowItemIndex
] = {
items: [updatedColumn],
title: this.formTitleData.title,
};
}
}
},
addItemToParent(updatedColumn) {
if (this.parentRowItemIndex)
this.$set(
this.localMainFormElements[this.currentTab].items,
this.parentRowItemIndex,
updatedColumn
);
else {
// find new item in the forms table columns items.
// if exist => continue
// else catch block executs and create new table columns.
try {
const res = this.localMainFormElements[this.currentTab].items.filter(
(item) => item.key == updatedColumn.key
);
if (res.length)
this.mySwalToast({
title: "ستونی با چنین مشخصاتی قبلا ایجاد شده است.",
html: null,
icon: "error",
});
else {
this.localMainFormElements[this.currentTab].items.push(
updatedColumn
);
}
} catch (msg) {
this.localMainFormElements[this.currentTab] = {
items: [updatedColumn],
title: this.formTitleData.title,
};
}
}
},
openChildNewFormItem(parentIndex) {
this.addToChildren = true;
this.parentRowItem =
this.localMainFormElements[this.currentTab].items[parentIndex];
this.childRowItem = undefined;
this.parentRowItemIndex = parentIndex;
this.childRowItemIndex = undefined;
this.$emit("open-new-form-item");
},
childEditNewFormItem(childIndex, parentIndex) {
this.addToChildren = true;
this.parentRowItem =
this.localMainFormElements[this.currentTab].items[parentIndex];
this.childRowItem =
this.localMainFormElements[this.currentTab].items[parentIndex].items[
childIndex
];
this.parentRowItemIndex = parentIndex;
this.childRowItemIndex = childIndex;
this.$emit("open-new-form-item", this.childRowItem);
},
editNewFormItem(index) {
this.addToChildren = false;
this.parentRowItem =
this.localMainFormElements[this.currentTab].items[index];
// this.parentRowItem = index;
this.$emit(
"open-new-form-item",
this.localMainFormElements[this.currentTab].items[index]
);
},
openNewFormItem() {
this.addToChildren = false;
// this.rowItem = {};
this.childRowItem = {};
this.parentRowItem = {};
this.$emit("open-new-form-item");
},
deleteChildItem(childIndex, parentIndex) {
this.mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
if (result.isConfirmed) {
{
this.localMainFormElements[this.currentTab].items[
parentIndex
].items.splice(childIndex, 1);
}
}
});
},
deleteItem(index) {
this.mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
if (result.isConfirmed) {
this.localMainFormElements[this.currentTab].items.splice(index, 1);
}
});
},
},
watch: {
newFormItem: {
handler(newVal) {
if (newVal) this.addFormItemToFormElements(newVal);
},
deep: true,
immediate: true,
},
},
};

View File

@ -0,0 +1,57 @@
{
"dashboard": [
{
"color": 1,
"icon": "Home-21",
"link": "home",
"title": "پیشخوان",
"subMenu": [],
"translateKey": "Dashboard"
}
],
"notifications": [
{
"icon": "Component-285--2",
"color": 3,
"link": "notifications",
"translateKey": "Notifications",
"title": "اعلانات"
}
],
"favorite": [
{
"color": 1,
"icon": "bookmark-1",
"link": "favorites",
"title": "علاقه مندی ها",
"translateKey": "Favorites",
"subMenu": [
{
"color": 5,
"icon": "bookmark-1",
"link": "favorites",
"title": "علامت ها",
"translateKey": "Marks"
},
{
"color": 5,
"icon": "bookmark-1",
"link": "histories",
"title": "تاریخچه",
"translateKey": "History"
}
]
}
],
"pages": [
{
"color": 1,
"icon": "question",
"link": "publicPagesModuleLayout",
"title": "",
"translateKey": "Pages",
"subMenu": []
}
]
}

View File

@ -0,0 +1,55 @@
{
"dashboard": [
{
"color": 1,
"icon": "Home-21",
"link": "home",
"title": "پیشخوان",
"subMenu": [],
"translateKey": "Dashboard"
},
{
"color": 1,
"icon": "layout-sections",
"link": "systems",
"title": "سامانه های من",
"translateKey": "systems",
"subMenu": []
}
],
"notifications": [
{
"icon": "Component-285--2",
"color": 3,
"link": "notifications",
"translateKey": "Notifications",
"title": "اعلانات"
}
],
"favorite": [
{
"color": 1,
"icon": "bookmark-1",
"link": "favorites",
"title": "علاقه مندی ها",
"translateKey": "Favorites",
"subMenu": [
{
"color": 5,
"icon": "bookmark-1",
"link": "favorites",
"title": "علامت ها",
"translateKey": "Marks"
},
{
"color": 5,
"icon": "bookmark-1",
"link": "histories",
"title": "تاریخچه",
"translateKey": "History"
}
]
}
]
}

View File

@ -0,0 +1,71 @@
[
{
"showOutside": true,
"show": true,
"icon": "tavasi tavasi-Component-71--1",
"title": "جزییات",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "btn show-detail-btn -rotate-180",
"action": "showDetails",
"can": "forms_show"
},
{
"showOutside": false,
"show": true,
"icon": "default",
"title": "ویرایش",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "edit-btn",
"action": "edit-table-item",
"can": "forms_edit"
},
{
"showOutside": false,
"show": true,
"icon": "default",
"title": "حذف",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "delete-btn",
"action": "delete-table-item",
"can": "forms_delete"
},
{
"showOutside": false,
"show": true,
"icon": "default",
"title": "ستون های فهرست",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "",
"action": "select-list-columns",
"can": "form_select-list-columns"
}
]

View File

@ -0,0 +1,34 @@
[
{
"showOutside": true,
"show": true,
"icon": "tavasi tavasi-Component-242--1",
"title": "ویرایش",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "",
"action": "edit-table-item",
"can": ""
},
{
"showOutside": true,
"show": true,
"icon": "tavasi tavasi-Component-295--1",
"title": "حذف",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "",
"action": "delete-table-item",
"can": ""
}
]

View File

@ -0,0 +1,36 @@
[
{
"showOutside": true,
"show": true,
"icon": "tavasi tavasi-Component-242--1",
"title": "ویرایش",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "edit-btn",
"action": "edit-table-item",
"can": ""
},
{
"showOutside": true,
"show": true,
"icon": "tavasi tavasi-Component-295--1",
"title": "حذف",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "delete-btn",
"action": "delete-table-item",
"can": ""
}
]

View File

@ -2,8 +2,10 @@
import fs from "fs-extra";
import path from "path";
const envs = import.meta.env;
let sassEnvVariables = "";
for (let e in import.meta.env) {
for (let e in envs) {
if (/VITE_/i.test(e)) {
sassEnvVariables += `$${e}: "${import.meta.env[e]}";`;
}
@ -74,7 +76,7 @@ export default defineNuxtConfig({
path: "/search/:key/:id/detail",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
// hadith
// --------------------- start: hadith routes ---------------------
{
name: "hadith",
path: "/hadith",
@ -85,11 +87,43 @@ export default defineNuxtConfig({
path: "/hadith/search",
file: "~/systems/hadith_ui/pages/hadith/search/index.vue",
},
// {
// name: "hadithShow",
// path: "/hadith/search/:id/:slug?",
// file: "~/systems/hadith_ui/pages/hadith/search/[id]/[slug]/index.vue",
// }
{
name: "hadithChatBot",
path: "/hadith/chat-bot",
file: "~/systems/hadith_ui/pages/hadith/chat-bot.vue",
},
{
name: "hadithFavorites",
path: "/hadith/favorites",
file: "~/systems/hadith_ui/pages/hadith/favorites/index.vue",
},
{
name: "hadithLibrary",
path: "/hadith/library",
file: "~/systems/hadith_ui/pages/hadith/library/index.vue",
},
{
name: "hadithLibraryShow",
path: "/hadith/library/:id/:slug?",
file: "~/systems/hadith_ui/pages/hadith/library/[id]/[slug]/index.vue",
},
{
name: "hadithAbout",
path: "/hadith/about-us",
file: "~/systems/hadith_ui/pages/hadith/public-pages/about-us.vue",
},
{
name: "hadithContact",
path: "/hadith/contact-us",
file: "~/systems/hadith_ui/pages/hadith/public-pages/ContactUs.vue",
},
{
name: "hadithRules",
path: "/hadith/rules",
file: "~/systems/hadith_ui/pages/hadith/public-pages/rules.vue",
}
// --------------------- end: hadith routes ---------------------
);
},
},

24
package-lock.json generated
View File

@ -11913,8 +11913,6 @@
},
"node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@ -12573,8 +12571,6 @@
},
"node_modules/npm/node_modules/cross-spawn/node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -13196,8 +13192,6 @@
},
"node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -13220,8 +13214,6 @@
},
"node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -13244,8 +13236,6 @@
},
"node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -13271,8 +13261,6 @@
},
"node_modules/npm/node_modules/minizlib/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -13407,8 +13395,6 @@
},
"node_modules/npm/node_modules/nopt/node_modules/abbrev": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
"integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
"inBundle": true,
"license": "ISC",
"engines": {
@ -14029,8 +14015,6 @@
},
"node_modules/npm/node_modules/tar/node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -14042,8 +14026,6 @@
},
"node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@ -14055,8 +14037,6 @@
},
"node_modules/npm/node_modules/tar/node_modules/minipass": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"inBundle": true,
"license": "ISC",
"engines": {
@ -14218,8 +14198,6 @@
},
"node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@ -14254,8 +14232,6 @@
},
"node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"inBundle": true,
"license": "MIT",
"dependencies": {

View File

@ -64,7 +64,6 @@ import { mapState, mapActions } from "pinia";
import searchApi from "~/apis/searchApi";
import { useStorage } from "@vueuse/core";
import { useCommonStore } from "~/stores/commonStore";
import { useSearchStore } from "~/stores/searchStore";
export default {
name: "guidesList",
@ -75,8 +74,7 @@ export default {
});
},
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(useCommonStore, ["organNameGetter"]),
...mapState(useCommonStore, ["organNameGetter","helpSchemaGetter"]),
// ...mapState(["organNameGetter"]),
@ -174,7 +172,7 @@ export default {
},
methods: {
// ...mapActions("search", ["helpSchemaSetter"]),
...mapActions(useSearchStore, ["helpSchemaSetter"]),
...mapActions(useCommonStore, ["helpSchemaSetter"]),
openModal(componentName, title) {
this.openSubjectForm = true;
this.slotComponentName = componentName;

View File

@ -84,7 +84,6 @@ import adminMenu from "~/json/admin/json/menu.json";
import { mapState, mapActions } from "pinia";
import { useStorage } from "@vueuse/core";
import { useCommonStore } from "~/stores/commonStore";
import { useSearchStore } from "~/stores/searchStore";
export default {
name: "adminGuides",
@ -99,8 +98,7 @@ export default {
this.httpService = useNuxtApp()["$http"];
},
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(useCommonStore, ["organNameGetter"]),
...mapState(useCommonStore, ["organNameGetter","helpSchemaGetter"]),
},
mounted() {
let localStoageHelpSchema = useStorage("settingSchema", undefined).value;
@ -142,7 +140,7 @@ export default {
},
methods: {
// ...mapActions("search", ["helpSchemaSetter"]),
...mapActions(useSearchStore, ["helpSchemaSetter"]),
...mapActions(useCommonStore, ["helpSchemaSetter"]),
// searchStore
select(e) {
this.value = e;

View File

@ -4,7 +4,11 @@
<template v-if="canView">
<div class="container-fluid no-gutters">
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-3" v-for="project in projects" :key="project.id">
<div
class="col-sm-12 col-md-6 col-lg-3"
v-for="project in projects"
:key="project.id"
>
<a
@click.prevent="redirectTo(project)"
:href="project.link"
@ -13,7 +17,8 @@
:title="project.title"
>
<div class="row no-gutters card-hover flex-grow-1">
<div class="col-md-2 d-flex justify-content-center align-items-center"
<div
class="col-md-2 d-flex justify-content-center align-items-center"
>
<img
:src="projectIcon(project.link)"
@ -22,14 +27,13 @@
/>
</div>
<div class="col-md-10 d-flex align-items-center">
<div class="card-body text-dark">
<h5 class="card-title">
{{ $t(project.link) }}
</h5>
<p class="card-text">
{{ $t(project.link+'Description') }}
{{ $t(project.link + "Description") }}
</p>
</div>
</div>
@ -44,8 +48,12 @@
<the-content-loading v-if="fetchingData"></the-content-loading>
<div v-else class="d-flex justify-content-center align-items-center">
<div class="alert alert-warning d-flex justify-content-center align-items-center">
<span class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"></span>
<div
class="alert alert-warning d-flex justify-content-center align-items-center"
>
<span
class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"
></span>
{{ $t("NoFindData") }}
</div>
</div>
@ -55,8 +63,10 @@
</template>
<script>
import apis from "@permission/permitApi";
import { mapGetters, mapMutations, mapActions } from "vuex";
import apis from "@apis/permitApi";
import { mapState, mapActions } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
import { usePermitStore } from "~/stores/permitStore";
export default {
data() {
@ -67,11 +77,11 @@ export default {
};
},
computed: {
...mapGetters("permit", ["projectGetter"]),
...mapState(usePermitStore, ["projectGetter"]),
},
methods: {
...mapMutations("permit", ["SET_PROJECT"]),
...mapActions(["checkPermissions"]),
...mapActions(usePermitStore, ["SET_PROJECT"]),
...mapActions(useCommonStore, ["checkPermissions"]),
projectIcon(name) {
try {

View File

@ -61,7 +61,7 @@
</template>
<script>
// import apis from "@permission/permitApi";
// import apis from "@apis/permitApi";
import apis from "~/apis/permitApi";
import adminMenu from "~/json/admin/json/menu.json";
import { defineAsyncComponent } from "vue";

View File

@ -182,18 +182,19 @@
</template>
<script>
import apis from "@permission/permitApi";
import { mapGetters } from "vuex";
import apis from "@apis/permitApi";
import { mapState } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
export default {
name: "UserAccessCustomization",
components: {
BreadCrumb: () => import("@components/BreadCrumb.vue"),
Share: () => import("@view/modal/Share.vue"),
Accordion: () => import("@permission/components/Accordion.vue"),
BreadCrumb: () => import("@components/global/BreadCrumb.vue"),
Share: () => import("@components/admin/modal/Share.vue"),
Accordion: () => import("@components/admin/components/Accordion.vue"),
},
computed: {
...mapGetters(["projectGetter"]),
...mapState(useCommonStore,["projectGetter"]),
},
props: {
items: {

View File

@ -92,9 +92,9 @@
</template>
<script>
// import apis from "@permission/permitApi";
// import apis from "@apis/permitApi";
// import { mapGetters, mapMutations, mapActions } from "vuex";
// import Share from "@permission/modal/Share.vue";
// import Share from "@apis/modal/Share.vue";
import apis from "~/apis/permitApi";
import adminMenu from "~/json/admin/json/menu.json";
import { defineAsyncComponent } from "vue";
@ -501,7 +501,7 @@ export default {
},
components: {
// BreadCrumb: () => import("@components/BreadCrumb.vue"),
// Accordion: () => import("@permission/components/Accordion.vue"),
// Accordion: () => import("@components/Accordion.vue"),
// SubHeaderWithSelect: defineAsyncComponent(() =>
// import("@/components/global/SubHeaderWithSelect.vue")
// ),

View File

@ -57,11 +57,11 @@
<div class="form-row">
<div class="col">
<label for="" class="mt-2">توضیح مفصل:</label>
<VueEditor
<!-- <VueEditor
dir="rtl"
v-model="editorData"
:editorOptions="editorOptions"
></VueEditor>
></VueEditor> -->
</div>
</div>
</form>
@ -72,7 +72,8 @@
<script>
import settingsApi from "~/apis/settingsApi";
import { VueEditor } from "vue2-editor";
// todo: install vueeditor for nuxt3/vue3
// import { VueEditor } from "vue2-editor";
import { mapState, mapActions } from "pinia";
import searchApi from "~/apis/searchApi";
import { useStorage } from "@vueuse/core";

View File

@ -17,7 +17,7 @@
<script>
import { mapState, mapActions } from "pinia";
import menu from "@dashboard/default/json/menu.json";
import menu from "@json/dashboard/default/json/menu.json";
import {clearBodyClass} from "@manuals/utilities"

BIN
public/img/location.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@ -0,0 +1,3 @@
<svg width="140" height="201" viewBox="0 0 140 201" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="0.28418" width="140" height="200" rx="8" fill="#D9D9D9"/>
</svg>

After

Width:  |  Height:  |  Size: 174 B

BIN
public/img/save-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/img/save.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -22,13 +22,16 @@ import type {
import type { researchTerms } from "~/types/researchTypes";
import type { ActiveEntityViewSchema, ActiveTab } from "~/types/entityType";
import type { Domain } from "~/types/searchTypes";
import type { Domain, helpActiveSchema, helpSchema } from "~/types/searchTypes";
export const useCommonStore = defineStore("commonStore", {
persist: {
storage: piniaPluginPersistedstate.localStorage(),
},
state: () => ({
// admin
helpSchema: undefined as helpSchema | undefined,
helpActiveSchema: undefined as helpActiveSchema | undefined,
// from search
domainActive: undefined as Domain | undefined,
@ -86,6 +89,13 @@ export const useCommonStore = defineStore("commonStore", {
sidebarMenu: {},
}),
getters: {
// admin
helpSchemaGetter(state) {
return state.helpSchema;
},
helpActiveSchemaGetter(state) {
return state.helpActiveSchema;
},
// from search
domainActiveGetter(state) {
return state.domainActive;
@ -145,6 +155,13 @@ export const useCommonStore = defineStore("commonStore", {
isShowHilightGetter: (state) => state.isShowHilight,
},
actions: {
// admin
helpSchemaSetter(helpSchema = undefined) {
this.helpSchema = helpSchema;
},
helpActiveSchemaSetter(helpActiveSchema = undefined) {
this.helpActiveSchema = helpActiveSchema;
},
// from search
domainActiveSetter(domain = undefined) {
this.domainActive = domain;

View File

@ -1,164 +0,0 @@
import type {
activeSearchChartSchema,
activeSearchListSchema,
Domain,
helpActiveSchema,
helpSchema,
searchActiveTab,
searchChartActiveTab,
searchListActiveTab,
searchSchema,
searchSynonymForm,
searchSynonymTitle,
selectionFilterItems,
} from "~/types/searchTypes";
export const useSearchStore = defineStore("searchStore", {
persist: {
storage: piniaPluginPersistedstate.localStorage(),
}, state: () => ({
domainActive: undefined as Domain | undefined,
// activeTab: undefined,
searchActiveTab: undefined as searchActiveTab | undefined,
searchSchema: undefined as searchSchema | undefined,
helpSchema: undefined as helpSchema | undefined,
searchActiveSchema: undefined as searchActiveTab | undefined,
helpActiveSchema: undefined as helpActiveSchema | undefined,
searchListActiveTab: undefined as searchListActiveTab | undefined,
searchListSchema: undefined as searchListActiveTab[] | undefined,
activeSearchListSchema: undefined as activeSearchListSchema | undefined,
searchChartActiveTab: undefined as searchChartActiveTab | undefined,
searchChartSchema: undefined as searchChartActiveTab[] | undefined,
activeSearchChartSchema: undefined as activeSearchChartSchema | undefined,
searchSynonymTitle: undefined as searchSynonymTitle | undefined,
searchSynonymForm: undefined as searchSynonymForm | undefined,
selectionFilterItems: [] as selectionFilterItems,
}),
getters: {
searchSynonymTitleGetter(state) {
return state.searchSynonymTitle;
},
searchSynonymFormGetter(state) {
return state.searchSynonymForm;
},
domainActiveGetter(state) {
return state.domainActive;
},
// activeTabGetter(state) {
// return state.activeTab;
// },
// search page
searchActiveTabGetter(state) {
return state.searchActiveTab;
},
searchSchemaGetter(state) {
return state.searchSchema;
},
helpSchemaGetter(state) {
return state.helpSchema;
},
helpActiveSchemaGetter(state) {
return state.helpActiveSchema;
},
searchActiveSchemaGetter(state) {
return state.searchActiveSchema;
},
// search list
searchListActiveTabGetter(state) {
return state.searchListActiveTab;
},
searchListSchemaGetter(state) {
return state.searchListSchema;
},
searchListActiveSchemaGetter(state) {
return state.activeSearchListSchema;
},
// search chart
searchChartActiveTabGetter(state) {
return state.searchChartActiveTab;
},
searchChartSchemaGetter(state) {
return state.searchChartSchema;
},
searchChartActiveSchemaGetter(state) {
return state.activeSearchChartSchema;
},
selectionFilterItemsGetter(state) {
return state.selectionFilterItems;
},
},
actions: {
searchSynonymFormSetter(searchSynonymForm = undefined) {
this.searchSynonymForm = searchSynonymForm;
},
searchSynonymTitleSetter(searchSynonymTitle = undefined) {
this.searchSynonymTitle = searchSynonymTitle;
},
domainActiveSetter(domain = undefined) {
this.domainActive = domain;
},
// activeTabSetter(activeTab = undefined) {
// this.activeTab = activeTab;
// },
// search page
searchActiveTabSetter(searchActiveTab: searchActiveTab = undefined) {
this.searchActiveTab = searchActiveTab;
},
searchSchemaSetter(searchSchema = undefined) {
this.searchSchema = searchSchema;
},
helpSchemaSetter(helpSchema = undefined) {
this.helpSchema = helpSchema;
},
helpActiveSchemaSetter(helpActiveSchema = undefined) {
this.helpActiveSchema = helpActiveSchema;
},
searchActiveSchemaSetter(searchActiveSchema = undefined) {
this.searchActiveSchema = searchActiveSchema;
},
// search list
searchListActiveTabSetter(searchListActiveTab = undefined) {
this.searchListActiveTab = searchListActiveTab;
},
searchListSchemaSetter(searchListSchema = undefined) {
this.searchListSchema = searchListSchema;
},
searchListActiveSchemaSetter(activeSearchListSchema = undefined) {
this.activeSearchListSchema = activeSearchListSchema;
},
// search chart
searchChartActiveTabSetter(searchChartActiveTab = undefined) {
this.searchChartActiveTab = searchChartActiveTab;
},
searchChartSchemaSetter(searchChartSchema = undefined) {
this.searchChartSchema = searchChartSchema;
},
searchChartActiveSchemaSetter(activeSearchChartSchema = undefined) {
this.activeSearchChartSchema = activeSearchChartSchema;
},
selectionFilterItemsSetter(selectionFilterItems = []) {
this.selectionFilterItems = <selectionFilterItems>selectionFilterItems;
},
},
});
// export default {
// namespaced:true,
// state,
// actions,
// mutations,
// getters
// };

@ -1 +1 @@
Subproject commit 0b606984b6e6c561f03df702a1cff19fb00ba054
Subproject commit 29e3034e3fa2e28142ae58934b9bad4dc2ce98f4

@ -1 +1 @@
Subproject commit 79d854a9912878646da9eba6a06eedb0bbd0bf90
Subproject commit 9a5f23287ffa2b970b17f5d1ab83cf8e6f5cc025