Compare commits

..

8 Commits
search ... main

Author SHA1 Message Date
mustafa-rezae
55cbde982e Add and config tailwind v4 and nuxtui 3 2025-02-12 17:44:17 +03:30
mustafa-rezae
106e9f83b9 Fix tailwind bug. 2025-02-12 12:04:30 +03:30
mustafa-rezae
31ed6095f7 install and update tailwind to v4 2025-02-11 16:22:39 +03:30
mustafa-rezae
a4c2950d93 add hadith_ui 2025-02-11 16:19:35 +03:30
mustafa-rezae
db6aade3d4 Update and add hadith 2025-02-11 16:19:14 +03:30
mustafa-rezae
2d2fbd0b99 Add hadith ui 2025-02-11 14:56:42 +03:30
mustafa-rezae
a43c48daee update systems. 2025-02-11 10:39:49 +03:30
mustafa-rezae
7ddda745c0 Update base 2025-02-11 10:38:54 +03:30
46 changed files with 5352 additions and 6857 deletions

1
.env
View File

@ -41,6 +41,7 @@ VITE_LANG = fa
VITE_APP_VERSION = 12890323
# all available systems, using for setting body class
VITE_HADITH_SYSTEM=hadith-system
VITE_RESEARCH_SYSTEM=research-system
VITE_SEARCH_SYSTEM=search-system
VITE_JAHAT_SYSTEM=jahat-system

54
.env.hadith Normal file
View File

@ -0,0 +1,54 @@
VITE_API_NAME=api/
VITE_BASE_URL=http://192.168.23.60/
VITE_APP_NAME=Hadith
### Relative pathes for systems sass addressing ###
# 0 : majles.tavasi.ir 1: qanon.parliran.ir
VITE_BUILD_STATE=0
VITE_BUILD_NAME=hadith
VITE_IDB_NAME=hadith
VITE_IDB_VERSION=1
VITE_ENABLE_IDB=1
### Page titles variables ###
VITE_TITLE=هم‌فهمی - زیست بوم پژوهشگران
VITE_DESCRIPTION=زیست بوم پژوهشگران
VITE_SHORT_TITLE=هم فهمی
VITE_LIST_PAGE_TITLE=هم فهمی - سامانه فهرست
VITE_SEARCH_PAGE_TITLE=هم فهمی - سامانه جستجوی محتوا
VITE_JAHAT_PAGE_TITLE=هم فهمی - سامانه هدایت تحقیقات جهت
VITE_TAHRIR_PAGE_TITLE=هم فهمی - سامانه ای برای سندنگار ابری حوزوی ، ابزار پژوهشگر
VITE_REPORT_PAGE_TITLE=هم فهمی - سامانه گزارش گیری داده
VITE_PERMISSION_PAGE_TITLE=هم فهمی - سامانه کنترل وظایف
VITE_RESEARCH_PAGE_TITLE = هم فهمی - تحقیقات من
VITE_CHAT_PAGE_TITLE=هم فهمی - سامانه گفتگو
VITE_AI_TOOLS_PAGE_TITLE = قانون‌یار - حاشیه نویسی
VITE_HADITH_PAGE_TITLE = حدیثا
VITE_USER_PANEL_PAGE_TITLE=هم فهمی - پیشخوان
VITE_DATA_SETTING_PAGE_TITLE=هم فهمی - تنظیمات داده
VITE_FORM_PAGE_TITLE=هم فهمی - فرم ها
VITE_NOTIFICATION_PAGE_TITLE=هم فهمی - اعلانات
VITE_PERMISSION_PAGE_TITLE=هم فهمی - دسترسی
VITE_REZOME_PAGE_TITLE=هم فهمی - رزومه ساز
VITE_SETTING_PAGE_TITLE=هم فهمی - تنظیمات
VITE_ENTITY_PAGE_TITLE=هم فهمی - نمایش جزئیات
VITE_BORHAN_PAGE_TITLE=هم فهمی - برهان
VITE_THIQAT_PAGE_TITLE=ثقات-گراف دانش حدیث
VITE_MAJLES_DASBOARD_TITLE1=مرجع رسمی قوانین و مقررات کشور
VITE_MAJLES_DASBOARD_TITLE2=هم‌فهمی
VITE_MAJLES_DASBOARD_TITLE3=(تنقیح هوشمند قوانین و مقررات)
VITE_MAJLES_DASBOARD_TITLE4= این سامانه با بهره گیری از ابزارهای هوش مصنوعی تهیه شده است.
VITE_MAJLES_DASBOARD_TITLE5= تمامی حقوق مادی و معنوی سایت، متعلق به مجلس شورای اسلامی می‌باشد.
VITE_VERSION=1.0.84
# modules
# [listRoutes, chatRoutes, tahrirRoutes, jahatRoutes, borhanRoutes, thiqatRoutes]
# VITE_BUILD_MODULES=listRoutes,tahrirRoutes,jahatRoutes,thiqatRoutes,chatRoutes
VITE_FONT_FAMILY=sahel

View File

@ -26,6 +26,7 @@ VITE_PERMISSION_PAGE_TITLE=هم فهمی - سامانه کنترل وظایف
VITE_RESEARCH_PAGE_TITLE = هم فهمی - تحقیقات من
VITE_CHAT_PAGE_TITLE=هم فهمی - سامانه گفتگو
VITE_AI_TOOLS_PAGE_TITLE = قانون‌یار - حاشیه نویسی
VITE_HADITH_PAGE_TITLE = حدیثا
VITE_USER_PANEL_PAGE_TITLE=هم فهمی - پیشخوان
VITE_DATA_SETTING_PAGE_TITLE=هم فهمی - تنظیمات داده

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "systems/search_ui"]
path = systems/search_ui
url = https://git2.tavasi.ir/front/search_ui.git
[submodule "systems/research_ui"]
path = systems/research_ui
url = https://git2.tavasi.ir/front/research_ui.git
[submodule "systems/hadith_ui"]
path = systems/hadith_ui
url = https://git2.tavasi.ir/front/hadith_ui.git

17
apis/aiToolsApi.js Normal file
View File

@ -0,0 +1,17 @@
export default {
schema: {
list: "schema",
},
MainContent: {
nextSection: "dataset/get/next",
update: "dataset/update/@task/@id",
update_result_objects: "dataset/update/result/object/@property_key/@id",
keywordAdd: "dataset/update/result/object/users/@id",
},
nlp: {
markdown: "ai/qanon/get/markdown",
markdown_section: "ai/qanon/get/markdown/section",
markdown_tree: "ai/qanon/get/markdown/tree",
effective_laws: "ai/laws/effective-laws",
},
};

86
apis/borhanApi.js Normal file
View File

@ -0,0 +1,86 @@
const baseUrl = "boronto/api/onto";
export default {
schema: {
list: "schema",
},
ontologies: {
show: `${baseUrl}/iri/`,
create: `${baseUrl}/`,
update: "",
delete: "",
read: "",
import: `${baseUrl}/import/`,
fileList: "/file/permit/borhan/list/serviceid",
},
imports: {
show: "",
create: `${baseUrl}/import/`,
update: `${baseUrl}/import/`,
delete: `${baseUrl}/import/`,
read: `${baseUrl}/import/`,
},
annotations: {
show: `${baseUrl}/annotation/`,
read: `${baseUrl}/annotation/`,
create: `${baseUrl}/annotation/`,
delete: `${baseUrl}/annotation/`,
},
metrics: {
read: `${baseUrl}/metric/`,
},
prefixes: {
read: `${baseUrl}/prefix/all/`,
},
iri: {
read: `${baseUrl}/iri/`,
update: `${baseUrl}/iri/`,
},
// همون مهفوم یا convept
class: {
sub: `${baseUrl}/class/sub/`,
equ: `${baseUrl}/class/equ/`,
read: `${baseUrl}/class/`,
add: `${baseUrl}/class/{{key}}/`,
removeAnnotation: `${baseUrl}/class/annotation/delete/`,
remove: `${baseUrl}/class/{{key}}/delete/`,
removetree: `${baseUrl}/class/delete/`,
autoComplate: `${baseUrl}/class/auto_complate/`,
update: `${baseUrl}/class/`,
annotations: {
read: `${baseUrl}/class/all/`,
},
},
property: {
removetree: `${baseUrl}/{{key}}/delete/`,
sub: `${baseUrl}/{{property}}/sub/`,
read: `${baseUrl}/all_property/`,
readitem: `${baseUrl}/{{key}}/`,
update: `${baseUrl}/property/`,
add: `${baseUrl}/property/{{key}}/`,
select: `${baseUrl}/property/type/`,
get_tree: `${baseUrl}/{{property}}/all/`,
annotations: {
read: `${baseUrl}/property/all/`,
read_all: `${baseUrl}/{{property}}/all/`,
},
},
individual: {
removetree: `${baseUrl}/individual/delete/`,
read: `${baseUrl}/all_individual/`,
add: `${baseUrl}/individual/{{key}}/`,
addlist: `${baseUrl}/individual/`,
select: `${baseUrl}/property/type/`,
update: `${baseUrl}/individual/`,
autoComplate: `${baseUrl}/individual/auto_complate/`,
remove: `${baseUrl}/individual/{{key}}/delete/`,
removList: `${baseUrl}/individual/delete/`,
removeAnnotation: `${baseUrl}/individual/annotation/delete/`,
annotations: {
read: `${baseUrl}/individual/all/`,
},
},
};

74
apis/chatApi.js Normal file
View File

@ -0,0 +1,74 @@
export default {
all: {
list: 'group/ve/get/groups/',
create: 'group/ed/set',
delete: 'group/ed/delete',
update: 'group/id',
edit: 'group/id',
updateAvatar: 'group/ed/avatar/',
},
groups: {
list: 'group/ve/get/groups/',
create: 'group/ed/set',
delete: 'group/ed/delete',
update: 'group/ed/set',
parent : 'group/ed/parent',
edit: 'group/id',
updateAvatar: 'group/ed/avatar/',
addMember: 'group/ed/setmembers/',
groupMembers: 'group/ve/members/ext/list/',
invite: 'group/invite',
leave: 'group/ed/leave',
},
lobbies: {
list: 'group/ve/get/lobby/1',
create: 'group/ed/set',
delete: 'group/ed/delete',
update: 'group/id',
edit: 'group/id',
updateAvatar: 'group/ed/avatar/',
},
privates: {
// list: 'message/private/list/',
list: 'message/private/list/similar/',
create: 'group/ed/set',
delete: 'message/delete',
update: 'group/id',
edit: 'group/id',
updateAvatar: 'group/ed/avatar/',
},
// myMessages: {
// list: "message/get/ext/",
// create: 'message/set',
// delete: 'message/id/delete',
// update: 'message/id',
// edit: 'message/id',
// },
unReads: {
list: "group/seen/list",
create: 'message/set',
delete: 'message/id/delete',
update: 'message/id',
edit: 'message/id',
groups: 'group/seen/group/',
privates: 'group/seen/user/',
},
messages: {
list: "message/get/ext/",
virtualList: "message/get/virtual/",
create: 'message/set',
delete: 'message/id/delete',
update: 'message/id',
edit: 'message/id',
show: 'message/get/info/@group_id/@messge_id',
},
// otherApi: {
// list: "message/get/group",
// update1:'message/get',
// },
}

50
apis/entityApi.js Normal file
View File

@ -0,0 +1,50 @@
export default {
schema: {
list: "schema",
},
research: {
addItem: "research/add/repo/{{index_key}}",
updateItem: "research/update/repo/{{index_key}}/{{id}}", //ایدی فیش و یا حاشیه
deleteItem: "/public/{{index_key}}/delete/{{id}}", //ایدی فیش و یا حاشیه
listByEntityId: "research/get/list/{{entity_id}}", // گرفتن لیست با ایدی
listByEntityIdByFilter: "research/get/list/{{entity_id}}/{{filter}}", // گرفتن لیست با ایدی و فیلتر //research_type=فیش&service=repo&ref_key:sanad&user_create:2
getByFilter: "research/get/list/{{filter}}", // گرفتن لیست با فیلتر
},
fish: {
save: "research/",
list: "research/getFishList/",
add: "research/add/repo/{{index_key}}",
addTerm: "research/add/term/repo/{{index_key}}/{{project_id}}",
update: "research/update/repo/{{index_key}}/{{id}}",
},
annotation: {
add: "research/add/repo/{{index_key}}",
update: "research/update/repo/{{index_key}}/{{id}}",
},
level: {
item: "version/get/step/{{sanad}}/{{entity_id}}?title={{title}}",
saveEdit: "version/step/{{sanad}}",
add: "version/step/sanad",
edit: "version/step/sanad/{{id}}",
delete: "/version/delete/step/sanad/{{id}}",
},
similar: {
// vector:"/majles/search/{{index_key}}/vector/{{sort_state}}/{{offset}}/{{limit}}",
textual: "/majles/similar/{{index_key}}/{{field}}/{{offset}}/{{limit}}",
},
chart: {
ganttchart: "repo/majles/ganttchart/{{index_key}}",
ganttchart2: "/majles/ganttchart/{{index_key}}/{{filter}}",
version: "repo/majles/version/@index_key",
},
// search: {
// default: "{{mode}}/data/{{params}}/{{sortKey}}/{{offset}}/{{limit}}",
// },
comparison: {
getParent: "/public/@index_key/text/parent/@parent_id",
getText: "/public/@index_key/text/@id",
},
edit: {
treeList: "tree/@index_key/@qanon_id",
},
};

6
apis/lmsApi.js Normal file
View File

@ -0,0 +1,6 @@
export default {
all: {
},
}

View File

@ -33,7 +33,8 @@ export default {
},
users: {
list: "/user/list/{{offset}}/{{limit}}/{{sortby}}/{{sortorder}}",
search: "/user/search/{{offset}}/{{limit}}/{{sortby}}/{{sortorder}}/{{query}}",
search:
"/user/search/{{offset}}/{{limit}}/{{sortby}}/{{sortorder}}/{{query}}",
create: "user/add",
update: "user/update",
updateUserState: "user/update/state",

View File

@ -18,6 +18,7 @@ export default {
draftList : '{{appname}}/draft/{{index_key}}/{{sortKey}}/{{offset}}/{{limit}}/{{filter}}',
draftSave : '{{appname}}/draft/{{index_key}}/saveto/{{to_index_key}}/{{entity_id}}',
draftUnlock : '{{appname}}/draft/{{index_key}}/unlock/{{to_index_key}}/{{entity_id}}',
textVersion : 'monir/steps/{{ref_key}}/{{ref_id}}'
// getCrition:"crition/bysubjectid/list/0/10/{{subjectId}}",
},
property: {

24
apis/researchApi.js Normal file
View File

@ -0,0 +1,24 @@
export default {
admin: {
list: "",
show: "",
edit: "",
update: "",
delete: "",
},
research:{
listDefault:"research/search/{{user_id}}/{{offset}}/{{limit}}",
listBySearch:"research/search/{{user_id}}/{{offset}}/{{limit}}/q=",
deleteItem: "/public/{{index_key}}/delete/{{id}}", //ایدی فیش و یا حاشیه
},
subject: {
move: 'subject/order/move/parent',
order: 'subject/order/move/one',
list: 'list/subject/list',
add: 'list/subject/add',
edit: 'list/subject/edit',
delete: 'list/subject/delete',
order: 'list/subject/order',
},
};

73
apis/searchApi.js Normal file
View File

@ -0,0 +1,73 @@
export default {
items: {
get: "monir/search/get/byid/",
},
Farhanghestan: {
search_normal: "monir/search/0/10",
search_And: "monir/search/and/0/10",
search_Phrase: "monir/search/phrase/0/10",
search_Code: "monir/search/code/all/0/10",
},
subject: {
add: "sanad/subject/add",
// edit: "sanad/subject/edit",
delete: "sanad/subject/delete",
order: "monir/sanad/subject/order",
},
index: {
Index_one: "safheh212/one",
index_multi: "safheh212/multi",
},
nesha: {
search_normal: "monir/search/nesha/0/10",
},
wordSWeight: {
list: "ngrams/elastic/{{index_key}}/1to3",
},
rezome: {
add: "rezumeh",
get: "rezumeh/get",
},
navigation: {
list: "navigate/list/@entity",
report:
"navigate/report/{{index_key}}/{{offset}}/{{limit}}/{{aggs}}/{{filter}}",
reportItem: "navigate/report/items",
reportSubjectItem: "navigate/report/subject={{subject_title}}/items",
},
bnavigation: {
list: "repo/navigate/list",
report: "repo/navigate/report",
reportItem: "repo/navigate/report/items",
reportSubjectItem: "repo/navigate/report/subject={{subject_title}}/items",
},
schema: {
list: "schema",
},
search: {
autoComplate:
"{{appname}}/complation/{{index_key}}/{{filter}}",
logAutoComplate:
"searchlog/complation/{{filter}}",
default:
"{{appname}}/data/{{index_key}}/{{sortKey}}/{{offset}}/{{limit}}/{{filter}}",
queryNormal:
"{{appname}}/search/{{index_key}}/{{search_type}}/{{sortKey}}/{{field_collapse}}/{{offset}}/{{limit}}/{{filter}}",
textSearch:
"{{appname}}/search/text/{{index_key}}/{{field}}/{{offset}}/{{limit}}/{{filter}}",
},
chart: {
timeline: "{{appname}}/data/timeline/{{index_key}}",
xy: "{{appname}}/data/xy/{{index_key}}/{{field_key}}",
items:
"navigate/report/items/search/{{index_key}}/{{offset}}/{{limit}}/{{filter}}",
chartTreeMap: "list/project/treemap/{{chart_key}}/{{filter}}",
treeItems:"navigate/report/items/search/{{index_key}}/{{offset}}/{{limit}}/{{filter}}",
tree: "list/subject/list",
graph:"repo/majles/{{to_key}}/relation"
},
synonym:{
getSynonyms:"synonym/get/words",
synonymSearch:"search/qasection/synonym/@listkey/@offset/@limit/@q",
}
};

37
apis/tahrirApi.js Normal file
View File

@ -0,0 +1,37 @@
export default {
users: {
list: 'user/list',
add: 'user/add'
},
profiles: {
list: 'profile/list',
add: 'profiles/add'
},
papers: {
list: 'project/list',
add: 'project/add'
},
docs: {
list: 'docs/list',
add: 'docs/add',
},
permissions: {
userPermissions: 'perm/add',
rolePermissions: 'perm/add'
},
comments: {
list: 'comment/20',
add: 'comment/add/20',
update: 'comment/edit/20',
documentComment: 'comment/parags/groupby/20',
addCommentToSelectedParag: 'paragraph/edit',
paragraphCommentList:'comment/20',
removeItem:'comment/delete/20',
replyto:'/comment/add/20',
},
moveOne: 'doc/order/move/one',
moveParent: 'doc/order/move/parent',
delete: 'doc/del',
}

34
apis/taskApi.js Normal file
View File

@ -0,0 +1,34 @@
export default {
workingHours: {
list: "general/get",
load: "general/load",
add: "general/add",
taskAdd: "details/add",
taskEdit: "details/edit",
day: "details/page/day",
delete: "details/delete",
deleteHours: "general/delete/time",
complitionAll: "details/complition/title",
complition: "details/complition/title/{{query}}",
copy: "general/copy",
move: "general/move",
},
taskChart: {
donut: "chart/getCategory",
},
taskTeams: {
getList: "group/list",
delete: "group/delete ",
edit: "group/edit ",
add:"group/add",
members:"perm/list",
addMembers:"perm/add",
deleteMembers:"perm/delete",
editMembers:"perm/edit",
},
taskReport: {
getList: "general/getList",
groupList:"group/list",
sortgroup:"general/load/group",
},
};

39
apis/thiqatApi.js Normal file
View File

@ -0,0 +1,39 @@
const baseUrl = "beta.thiqat.org/api/";
export default {
baseUrl: "https://beta.thiqat.org/api/",
ChartLine:"/persons/id/times?iri={{name}}",
schema: {
list: "schema",
},
entities: {
filter_model: "/filter_model/",
list: "/",
info: "/id/",
relations: "/relations/",
persons: {
filter_model: "persons/filter_model/",
list: "persons/",
info: "persons/id/",
relations: "persons/id/relations/",
stats: "persons/stats/",
correlation_stats: "persons/correlation_stats/",
},
hadiths: {
filter_model: "hadiths/filter_model",
list: "hadiths/",
info: "hadiths/id"
},
terms: {
filter_model: "terms/filter_model",
list: "terms/",
info: "terms/id"
}
},
persons: {
stats: "persons/stats/?parent_iri={{value}}",
// id:"persons/id/times?iri={{id}}",
id:"persons/id/times",
correlation:"persons/correlation_stats?parent1_iri={{id1}}&parent2_iri={{id2}}"
},
};

View File

@ -7,12 +7,14 @@ export default defineAppConfig({
fallback: "light", // Set the fallback to 'light' if system preference is not available
},
ui: {
primary: "green",
gray: "cool",
colors: {
primary: "emerald",
neutral: "slate",
},
button: {
default: {
color: "orange",
defaultVariants: {
// Set default button color to neutral
// color: 'neutral'
},
},
},

View File

@ -1,7 +1,7 @@
<template>
<div>
<UApp>
<NuxtLoadingIndicator />
<!-- <NuxtRouteAnnouncer /> -->
<NuxtRouteAnnouncer />
<!-- <DevOnly> -->
<!-- this component will only be rendered during development -->
<!-- <LazyDebugBar /> -->
@ -23,9 +23,8 @@
<NuxtPage />
<!-- <BrokeInSsr /> -->
<!-- </NuxtClientFallback> -->
</NuxtLayout>
</div>
</UApp>
</template>
<script>

12
assets/css/tailwind.css Normal file
View File

@ -0,0 +1,12 @@
/* @import "tailwindcss/tailwind.css"; */
@import "tailwindcss";
@import "@nuxt/ui";
@theme {
--font-sans: "Public Sans", sans-serif;
}
/* @variant {
} */
/* @source */

View File

@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -6,7 +6,7 @@
import * as echarts from "echarts";
import entityApi from "~/apis/entityApi.js";
import { mapState } from "pinia";
import { useEntityStore } from "~/stores/entityStore";
import { useCommonStore } from "~/stores/commonStore";
/**
* @vue-prop {Object|null} [selectedItem=null] - آیتم انتخاب شده
@ -44,7 +44,7 @@ export default {
};
},
computed: {
...mapState(useEntityStore, ["activeEntityViewSchemaGetter"]),
...mapState(useCommonStore, ["activeEntityViewSchemaGetter"]),
},
mounted() {
if (this.selectedItem) {

View File

@ -143,13 +143,12 @@
import researchApi from "@apis/researchApi";
import HttpService from "@services/httpService";
import { mapActions, mapState } from "pinia";
import { useResearchStore } from "~/stores/researchStore";
import { useCommonStore } from "~/stores/commonStore";
//
import { use } from "echarts/core";
import { TreeChart } from "echarts/charts";
import { TooltipComponent, ToolboxComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import { removeData } from "jquery";
use([TooltipComponent, TreeChart, CanvasRenderer, ToolboxComponent]);
/**
* @vue-prop {Array} [dataTreeMap=] - آرایهای از دادههای نقشه درخت
@ -393,14 +392,14 @@ export default {
this.option.toolbox.feature.myTool2.iconStyle.color = "#fff";
},
computed: {
...mapState(useResearchStore, [
"dataForTreeMapGetter",
...mapState(useCommonStore, [
// "dataForTreeMapGetter",
"researchTermsGetter",
]),
},
methods: {
...mapActions(useResearchStore, ["dataForTreeMapSetter"]),
// ...mapActions(useResearchStore, ["dataForTreeMapSetter"]),
/**
*تغیرات مربوط به حالت نمایش و ویرایش در چارت

View File

@ -1,549 +0,0 @@
<template>
<div
class="input-group"
@keyup="keyupdiv"
:style="{
showAppend: { 'box-shadow': '0 1px 3px rgba(23, 23, 23, 0.24)' },
}"
>
<div class="input-group-prepend">
<button
v-if="showPrepend"
dir="rtl"
class="btn d-flex align-items-center"
type="button"
id="button-addon2"
@click="searchNavigateList()"
>
جستجو
<span class="tavasi tavasi-Component-198--1"></span>
</button>
<span v-else style="opacity: 0">xxx</span>
</div>
<input
type="text"
v-model="localTextSearch"
@click="showHisory()"
@keyup.enter="prevSearchStart"
@keyup="toggleAutocomplete"
@keydown="onKeyDown()"
class="form-control"
id="search"
:placeholder="placeholder"
autocomplete="off"
ref="searchinput"
@focus="setInputFocus()"
@blur="inputfocused = false"
v-focus
/>
<div :class="[showAppend ? 'input-group-text' : 'input-group-append']">
<template v-if="showAppend">
<button
v-tooltip="'جستجو در خاصیت(فیلد) ویژه'"
class="btn dropdown-toggle dropdown-toggle-color rounded-0"
type="button"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
id="dropdownMenuButton12"
>
<span class="navItemlabel">
{{ domainActiveGetter?.label }}
</span>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton12">
<button
v-for="(navItem, index) in searchDomain"
:key="index"
type="button"
class="dropdown-item"
@click.prevent="setDomainField(navItem)"
>
{{ navItem.label }}
</button>
</div>
</template>
<button
v-if="showAppendSearchButton"
v-tooltip="'جستجو در خاصیت(فیلد) ویژه'"
@click.prevent="prevSearchStart()"
class="btn btn-primary search-icon"
>
<svg class="icon icon-Component-198--1">
<use xlink:href="#icon-Component-198--1"></use>
</svg>
<!-- <NuxtImg src="@assets/common/img/searchmajles.svg" alt="" /> -->
</button>
</div>
<div
v-if="inputPopupState == 3 && localListAutocomplate.length"
class="search-page__result firefox-scrollbar"
:class="{
show: localListAutocomplate.length,
}"
>
<!-- v-click-outside="onClickOutside" -->
<ul ref="auto_complate_ul">
<li v-for="(item, i) in localListAutocomplate" :key="i" :value="i">
<a @click.prevent="selectAutocomplate2(item)">
<span
class="text__14"
v-html="getHighlightAutocomplate(item)"
></span>
</a>
</li>
</ul>
</div>
<div
v-if="inputPopupState == 1"
class="search-page__result show"
>
<!-- v-click-outside="onClickOutside" -->
<template v-if="historySearch.length">
<div>
<div class="scrollbar">
<ul ref="his_ul">
<li v-for="(item, i) in historySearch" :key="i" :data-key="i">
<a @click.prevent="selectHistorySearch(item)">
<NuxtImg src="assets/common/img/Component 359 2.svg" alt="" />
<span class="text__14">{{ item }}</span>
</a>
<a @click="removeHistorySearch(i)" class="close">
<svg class="icon icon-Component-294--1">
<use xlink:href="#icon-Component-294--1"></use>
</svg>
</a>
</li>
</ul>
</div>
</div>
</template>
<template v-else>
<div class="scrollbar">
<ul ref="">
<li>
<p class="m-0 text__light">
<NuxtImg src="assets/common/img/Component 359 2.svg" alt="" />
<span class="text__14"> تاریخچه جستجو خالی می باشد </span>
</p>
</li>
</ul>
</div>
</template>
</div>
</div>
</template>
<script>
import { mapState } from "pinia";
import searchApi from "~/apis/searchApi";
import { useSearchStore } from "~/stores/searchStore";
// Vue.directive("click-outside", {
// bind(el, binding, vnode) {
// el.clickOutsideEvent = (event) => {
// if (!(el === event.target || el.contains(event.target))) {
// vnode.context[binding.expression](event);
// }
// };
// document.body.addEventListener("click", el.clickOutsideEvent);
// },
// unbind(el) {
// document.body.removeEventListener("click", el.clickOutsideEvent);
// },
// });
export default {
props: {
placeholder: {
default: "جستجو در هزاران محتوای قوانین و مقرارت",
},
contentKey: {
default: "qasection",
},
entityTheme: {
default: false,
},
showAppendSearchButton: {
default: true,
},
showPrepend: {
default: false,
},
showAppend: {
default: true,
},
textSearch: {
default: "",
},
modeInit: {
default: 0,
},
searchDomain: {
default() {
return [];
},
},
listAutocomplate: {
default() {
return [];
},
},
},
emits: ["getAutoComplateList"],
watch: {
modeInit(newVal = 1) {
this.mode = newVal;
},
textSearch(newVal) {
this.localTextSearch = newVal;
},
},
beforeMount() {
// this.inputPopupState = this.inputPopupState;
},
mounted() {
this.localTextSearch = this.textSearch;
if (window.localStorage.getItem([this.historySearchRecent])) {
try {
this.historySearch = JSON.parse(
window.localStorage.getItem([this.historySearchRecent])
);
} catch (e) {
window.localStorage.removeItem([this.historySearchRecent]);
}
}
},
beforeDestroy() {
window.removeEventListener("resize", this.handleResize);
window.removeEventListener("load", this.handleResize);
document.removeEventListener("click", this.handleClickOutside);
},
data() {
return {
localListAutocomplate: [],
typingTimer: undefined,
doneTypingInterval: 800,
localTextSearch: "",
historySearch: [],
inputPopupState: 0,
mode: 1,
tagLiSelected: null,
inputfocused: false,
isLastKeyCodeArrow: false,
historySearchRecent: "historysearchrecent",
};
},
computed: {
...mapState(useSearchStore, [
"domainActiveGetter",
"searchActiveTabGetter",
"searchSchemaGetter",
"searchSynonymTitleGetter",
]),
},
methods: {
/**
* تنظیم آیتم انتخاب شده و شروع جستجو.
* @param {Object} navItem - آیتم انتخابشده.
*/
setDomainField(navItem) {
this.$emit("onSetDomainField", navItem);
// this.prevSearchStart();
},
async getAutoComplateList() {
this.localListAutocomplate = [];
if (this.localTextSearch == "") return;
let index_key = this.contentKey;
if (!index_key) return;
let url = searchApi.search.autoComplate;
url = url.replace("{{appname}}", buildName());
url = url.replace("{{index_key}}", index_key);
url = url.replace("{{filter}}", "q=" + this.localTextSearch);
try {
const { $api } = useNuxtApp();
const response = await $api(url, {
baseURL: repoUrl(),
});
this.localListAutocomplate = response.hits?.hits;
this.inputPopupState = 3;
} catch (err) {}
},
onKeyDown() {
clearTimeout(this.typingTimer);
this.typingTimer = undefined;
},
/**
* کنترل تایمر تکمیل خودکار و ارسال کوئری.
* تایمر فعلی را پاک میکند و یک تایمر جدید با یک تاخیر مشخص تنظیم میکند تا کوئری را ارسال کند.
*/
toggleAutocomplete(event) {
// برای کلید حرکت پایین درخواست اضافی نرود
if (
event.keyCode === 40 ||
event.keyCode === 38 ||
event.keyCode === 13
) {
this.isLastKeyCodeArrow = event.keyCode === 40 || event.keyCode === 38;
return;
}
this.isLastKeyCodeArrow = false;
if (!this.inputfocused && this.inputPopupState === 3) {
return;
}
if (this.typingTimer) {
clearTimeout(this.typingTimer);
this.typingTimer = undefined;
} else {
this.typingTimer = setTimeout(() => {
this.getAutoComplateList();
this.typingTimer = undefined;
}, this.doneTypingInterval);
}
},
setInputFocus() {
this.inputfocused = true;
// this.inputPopupfocused=false
},
/**
* شروع جستجو را کنترل میکند.
* @event prevSearchStart
*/
prevSearchStart(event) {
if (
this.isLastKeyCodeArrow &&
event.keyCode === 13 &&
this.inputPopupState != 0
) {
this.selectAutocomplate2();
this.isLastKeyCodeArrow = false;
return;
}
this.tagLiSelected = null;
this.inputPopupState = 0;
this.addHistorySearch(this.localTextSearch);
let tt = myEncodeQuery(this.localTextSearch);
this.$emit("onSearchStart", tt);
// this.searchStart(tt);
},
/**
*نمایش سابقه جستجو.
*/
showHisory() {
setTimeout(() => {
if (this.localTextSearch == "") this.inputPopupState = 1;
else {
this.inputPopupState = 0;
this.tagLiSelected = null;
}
}, 100);
},
/**
* کنترل کلیکهای خارج از المان.
*/
keyupdiv(event) {
// 13:enter
// 8:backspace
if (this.inputfocused == false) return;
if (this.inputPopupState == 0 || this.inputPopupState == 2) return;
var el = "";
el =
this.inputPopupState == 1
? this.$refs["his_ul"]
: this.$refs["auto_complate_ul"];
if (!el || !el.firstChild) return;
const selectItem = (item) => {
this.tagLiSelected = item;
this.tagLiSelected?.classList.add("selected");
this.tagLiSelected?.focus();
};
// 40: arrow down
// 38: arrow up
if (this.inputfocused == true && event.keyCode === 40) {
if (this.tagLiSelected) {
this.tagLiSelected?.classList.remove("selected");
const next = this.tagLiSelected?.nextSibling || el.firstChild;
selectItem(next);
} else {
selectItem(el?.firstChild);
}
} else if (this.inputfocused == true && event.keyCode === 38) {
if (this.tagLiSelected) {
this.tagLiSelected?.classList.remove("selected");
const prev = this.tagLiSelected?.previousSibling || el.lastChild;
selectItem(prev);
} else {
selectItem(el?.lastChild);
}
}
// 46: delete
else if (this.inputfocused == true && event.keyCode === 46) {
let index = this.tagLiSelected?.getAttribute("data-key");
this.removeHistorySearch(index);
}
},
onClickOutside() {
if (this.inputPopupState == 1 || this.inputPopupState == 3) {
this.inputPopupState = 0;
this.tagLiSelected = null;
}
},
selectAutocomplate(item) {
this.tagLiSelected = null;
this.inputPopupState = 0;
this.localTextSearch = item;
this.$emit("onSearchStart", this.localTextSearch);
// this.$emit("onSearchStart", {
// textSearch: this.localTextSearch,
// searchItem: item,
// });
},
selectHistorySearch(item) {
this.localTextSearch = item;
this.$emit("onSearchStart", this.localTextSearch);
},
removeHistorySearch(x) {
this.tagLiSelected = null;
this.historySearch.splice(x, 1);
this.saveHistorySearch();
},
saveHistorySearch() {
const parsed = JSON.stringify(this.historySearch);
window.localStorage.setItem([this.historySearchRecent], parsed);
},
getHighlightAutocomplate(item) {
if (!item) return "";
let html = "";
let key = "title";
if (this.contentKey == "qasection" || this.contentKey == "rgsection") {
key = "qanon_title";
if (item?.highlight[key]) html = item.highlight[key][0];
if (!html) {
let key1 = key + ".ph";
if (item?.highlight[key1]) html = item.highlight[key1][0];
}
if (!html) {
let key1 = key + ".fa";
if (item?.highlight[key1]) html = item.highlight[key1][0];
}
let key2 = "ts_date";
if (item?._source[key2]) {
html += `<span style="color: #a7a098;"> - تاریخ: ${item._source[key2]}</span>`;
}
}
if (this.contentKey == "sanad") {
Object.values(item?.highlight).forEach((element, index) => {
html += element[0];
});
}
return html;
},
addHistorySearch(newSearch = "") {
if (newSearch == "") {
return;
}
var index = this.historySearch.indexOf(newSearch);
if (index != -1) {
this.historySearch.splice(index, 1);
}
this.historySearch.unshift(newSearch);
this.saveHistorySearch();
},
saveHistorySearch() {
const parsed = JSON.stringify(this.historySearch);
window.localStorage.setItem([this.historySearchRecent], parsed);
},
selectAutocomplate2(item) {
if (!item) {
if (this.localListAutocomplate.length) {
item = this.localListAutocomplate[this.tagLiSelected?.value];
}
}
let key = "title";
if (this.contentKey == "qasection" || this.contentKey == "rgsection")
key = "qanon_title";
this.inputfocused = false;
this.searchinput?.blur();
this.localTextSearch = item?._source[key];
this.$emit("onSearchStart", this.localTextSearch);
// this.$emit("onSearchStart", {
// textSearch: this.localTextSearch,
// searchItem: item,
// });
if (!item) {
this.localTextSearch = this.tagLiSelected?.innerText;
this.addHistorySearch(this.localTextSearch);
let tt = myEncodeQuery(this.localTextSearch);
this.$emit("onSearchStart", tt);
// this.$emit("onSearchStart", { textSearch: tt, searchItem: item });
}
this.inputPopupState = 0;
this.tagLiSelected = null;
},
},
};
</script>
<style lang="scss" scoped>
.entityTheme {
.btn {
border-radius: 0.5rem 0 0 0.5rem !important;
}
}
.close {
svg {
font-size: 0.5em;
&:hover {
color: #ef4444 !important;
}
}
}
.search-page__result.show {
border-radius: 0.5em !important;
}
.input-group-text {
background-color: #fff !important;
}
</style>

View File

@ -0,0 +1,27 @@
<script setup>
const colorMode = useColorMode()
const isDark = computed({
get() {
return colorMode.value === 'dark'
},
set() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>
<template>
<ClientOnly v-if="!colorMode?.forced">
<UButton
:icon="isDark ? 'i-lucide-moon' : 'i-lucide-sun'"
color="neutral"
variant="ghost"
@click="isDark = !isDark"
/>
<template #fallback>
<div class="size-8" />
</template>
</ClientOnly>
</template>

View File

@ -84,7 +84,7 @@
<script>
import repoApi from "~/apis/repoApi";
import { mapState } from "pinia";
import { useEntityStore } from "~/stores/entityStore";
import { useCommonStore } from "~/stores/commonStore";
import SelectComponentDefault from "~/components/SelectComponentDefault.vue";
import SelectComponent from "~/components/SelectComponent.vue";
@ -152,7 +152,7 @@ export default {
};
},
computed: {
...mapState(useEntityStore, [
...mapState(useCommonStore, [
// "selectedItemEntityGetter",
"activeTabGetter",
]),

View File

@ -1,56 +0,0 @@
<template>
<main :class="$route.name">
<the-sidebar
:showUserAvatar="true"
:menu="$attrs.menu"
@statusPag="statusPag"
></the-sidebar>
<section
class="main-page__content"
:class="{ expanded: !isSidebarCollapsed }"
>
<slot name="named-slot"></slot>
<slot></slot>
</section>
</main>
</template>
<script>
// import { mapActions, mapState } from "pinia";
// import { useCommonStore } from "~/stores/commonStore";
import {clearBodyClass} from "@manuals/utilities"
export default {
beforeMount() {
clearBodyClass();
// this.uuid = Math.floor(Math.random() * 100);
// document.title = import.meta.env.VITE_SEARCH_PAGE_TITLE;
},
// mounted() {
// this.setBodyClass(this.$attrs.bodyClass);
// },
destroyed() {
clearBodyClass();
},
data() {
return {
uuid: undefined,
};
},
// methods: {
// ...mapActions(useCommonStore, ["setBodyClass"]),
// },
};
</script>
<style lang="scss">
/*@import "../../assets/scss/projects/tahrir/tahrir";*/
/*@import "../../assets/scss/projects/list/list";*/
@import "../assets/search/scss/search";
.search-system .modal-backdrop.show {
display: block;
background-color: #0000003b;
}
</style>

View File

@ -0,0 +1,4 @@
// middleware/redirect.js
export default defineNuxtRouteMiddleware((to, from) => {
if (buildName() == "hadith" && to.path == '/') return navigateTo({ name: "hadith" });
});

View File

@ -1,13 +0,0 @@
// middleware/redirect.js
export default defineNuxtRouteMiddleware((to, from) => {
// to.path = to.path
// .replace("id", from.params.id)
// .replace("key", from.params.key);
// to.params = from.params
// console.info(from);
// console.info(to);
return;
});

View File

@ -1,5 +1,5 @@
import apis from "~/apis/listApi";
import { useListStore } from "~/stores/listStore";
import { useSearchStore } from "@search/stores/searchStore";
interface FormData {
id: string | number;
@ -48,7 +48,7 @@ export const moveFromFolderToFolder = async (
cloneId: string | number,
toId: string | number
) => {
const myStore = useListStore();
const myStore = useSearchStore();
const formData = {
id: cloneId,
newparent: toId ?? 0,
@ -59,7 +59,7 @@ export const moveFromFolderToFolder = async (
};
export const moveFromFolderToRoot = async (cloneId: string | number) => {
const myStore = useListStore();
const myStore = useSearchStore();
const formData = {
id: cloneId,
newparent: 0,
@ -73,7 +73,7 @@ export const moveFromRootToFolder = async (
cloneId: string | number,
toId: string | number
) => {
const myStore = useListStore();
const myStore = useSearchStore();
const formData = {
id: cloneId,
newparent: toId ?? 0,
@ -110,7 +110,7 @@ export const moveItem = async (formData: FormData) => {
};
export const addItemToList = async (itemId: string, listId: string) => {
const myStore = useListStore();
const myStore = useSearchStore();
const payload = {
itemid: itemId,
listid: listId,
@ -144,7 +144,7 @@ export const updateOrder = async (
listArray: [],
index: number
) => {
const myStore = useListStore();
const myStore = useSearchStore();
const payload = {
id: list.id,
offset: type === "move-up" ? -1 : 1,

View File

@ -1,4 +1,4 @@
import { fileURLToPath } from "url";
// import { fileURLToPath } from "url";
let sassEnvVariables = "";
for (let e in import.meta.env) {
@ -11,7 +11,59 @@ for (let e in import.meta.env) {
const buildName = import.meta.env.VITE_BUILD_NAME;
let mainStyle = `~/assets/common/scss/${buildName}-styles.scss`;
if (buildName == "hadith")
mainStyle = `~/systems/${buildName}_ui/assets/${buildName}/scss/${buildName}.scss`;
export default defineNuxtConfig({
hooks: {
"pages:extend"(pages) {
// Add custom routes
pages.push(
{
name: "search",
path: "/search",
file: "~/systems/search_ui/pages/search/index.vue",
},
{
name: "searchNavigation",
path: "/search/lists",
file: "~/systems/search_ui/pages/search/lists.vue",
},
{
name: "searchChart",
path: "/search/charts",
file: "~/systems/search_ui/pages/search/charts.vue",
},
{
name: "showEntity",
path: "/search/:key/:id/show",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "navigationView",
path: "/search/:key/:id/list",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "entityResearch",
path: "/search/:key/:id/research",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "entityResearch",
path: "/search/:key/:id/detail",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
// hadith
{
name: "hadith",
path: "/hadith",
file: "~/systems/hadith_ui/pages/hadith/index.vue",
}
);
},
},
nitro: {
compressPublicAssets: true,
},
@ -56,6 +108,14 @@ export default defineNuxtConfig({
"@nuxt/image",
// "@nuxtjs/supabase",
],
// ui: {
// prefix: 'Nuxt', //Use the prefix option to change the prefix of the components. Default: U
// fonts: false, // Use the fonts option to enable or disable the @nuxt/fonts module. Default: true
// colorMode: false, // Use the colorMode option to enable or disable the @nuxt/color-mode module. Default: true
// theme: {
// colors: ['primary', 'error'] // Use the theme.colors option to define the dynamic color aliases used to generate components theme.
// },
// },
// delayHydration: {
// // enables nuxt-delay-hydration in dev mode for testing
// debug: process.env.NODE_ENV === 'development',
@ -110,7 +170,7 @@ export default defineNuxtConfig({
},
css: [
mainStyle,
"~/assets/tailwindcss/main.css",
"~/assets/css/tailwind.css",
"vue3-persian-datetime-picker/src/picker/assets/scss/style.scss",
],
alias: {
@ -128,6 +188,9 @@ export default defineNuxtConfig({
"@utils": "~/utils",
"@manuals": "~/manuals",
"@pages": "~/pages",
"@search": "~/systems/search_ui",
"@research": "~/systems/research_ui",
"@hadith": "~/systems/hadith_ui",
},
vite: {
resolve: {},
@ -149,12 +212,12 @@ export default defineNuxtConfig({
},
},
},
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
// postcss: {
// plugins: {
// tailwindcss: {},
// autoprefixer: {},
// },
// },
// "~": "/<srcDir>",
// "@": "/<srcDir>",

6766
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,11 +10,12 @@
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"dev-tavasi": "env-cmd -f .env.tavasi nuxt dev --host --inspect",
"dev-monir": "env-cmd -f .env.monir nuxt dev --host --inspect"
"dev-monir": "env-cmd -f .env.monir nuxt dev --host --inspect",
"dev-hadith": "env-cmd -f .env.hadith nuxt dev --host --inspect"
},
"dependencies": {
"@nuxt/image": "^1.8.1",
"@nuxt/ui": "^2.18.7",
"@nuxt/ui": "^3.0.0-alpha.12",
"@nuxtjs/supabase": "^1.4.5",
"@pinia/nuxt": "^0.5.4",
"@popperjs/core": "^2.11.8",
@ -35,8 +36,7 @@
"jquery": "^3.7.1",
"mammoth": "^1.8.0",
"mitt": "^3.0.1",
"node-sass": "^9.0.0",
"nuxt": "^3.13.0",
"nuxt": "^3.15.4",
"nuxt-echarts": "^0.2.3",
"pinia-plugin-persistedstate": "^4.1.1",
"qrcode": "^1.5.4",
@ -71,10 +71,10 @@
"happy-dom": "^15.11.0",
"nuxt-moment-jalaali": "^1.6.2",
"playwright-core": "^1.48.2",
"postcss": "^8.4.49",
"postcss": "^8.5.2",
"postcss-import": "^16.1.0",
"sass-embedded": "^1.78.0",
"tailwindcss": "^3.4.16",
"tailwindcss": "^4.0.6",
"typescript": "^5.6.3",
"vitest": "^2.1.4",
"vue-tsc": "^2.1.6"

View File

@ -1,13 +0,0 @@
<script setup lang="ts"></script>
<template>
<h1>
About page.
</h1>
</template>
<style module>
.red {
color: red;
}
</style>

View File

@ -2,9 +2,9 @@
<div class="pages access-page p-3">
<sub-header-with-select
@open-form="toggleRolesPanel()"
:showProjectSelect="$attrs.showProjectSelect"
title="تنظیم دسترسی کاربران">
title="تنظیم دسترسی کاربران"
>
<!-- <button-->
<!-- @click="toggleRolesPanel()"-->
<!-- class="btn btn-outline-primary position-relative"-->
@ -17,106 +17,132 @@
<div class="table-responsive">
<table class="table table-borderless table-hover">
<thead>
<th colspan="12" class="px-0">
<form class="table-search-form" role="search">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<svg class="" aria-hidden="true" focusable="false"
data-prefix="fas" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512" data-fa-i2svg="">
<path fill="currentColor"
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg>
</span>
<tr>
<th colspan="12" class="px-0">
<form class="table-search-form" role="search">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<svg
class=""
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="search"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
data-fa-i2svg=""
>
<path
fill="currentColor"
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
></path>
</svg>
</span>
</div>
<input
v-model="searchForm.query"
type="search"
required
class="form-control"
id="search-query"
placeholder="جستجو..."
name="search-query"
aria-label="جستجو در اسناد، عناوین و واژگان"
aria-describedby="basic-addon1"
size="50"
/>
<div class="input-group-append">
<button
:class="{
'show-reset-btn': searchForm.query.length > 0,
}"
type="button"
class="input-group-text"
id="basic-addon1"
>
<i class="tavasi tavasi-Component-294--1"></i>
</button>
</div>
</div>
</div>
<input
v-model="searchForm.query"
type="search"
required
class="form-control"
id="search-query"
placeholder="جستجو..."
name="search-query"
aria-label="جستجو در اسناد، عناوین و واژگان"
aria-describedby="basic-addon1"
size="50"
>
<div class="input-group-append">
<button :class="{'show-reset-btn' : searchForm.query.length > 0}"
type="button"
class="input-group-text"
id="basic-addon1">
<i class="tavasi tavasi-Component-294--1"></i>
</button>
</div>
</div>
</div>
</form>
</th>
</form>
</th>
</tr>
</thead>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">نام</th>
<th scope="col">نقش</th>
<th scope="col">تاریخ ثبت نام</th>
<th scope="col">عملیات</th>
</tr>
<tr>
<th scope="col">#</th>
<th scope="col">نام</th>
<th scope="col">نقش</th>
<th scope="col">تاریخ ثبت نام</th>
<th scope="col">عملیات</th>
</tr>
</thead>
<tbody>
<template v-if="userRoles.length">
<tr v-for="({user,...item},index) in userRoles"
:class="{'active': item.active ?? false }" :key="index">
<th scope="row">{{ index + 1 }}</th>
<td>
<div class="user-info">
<div class="user-info-avatar">
<img :src="userAvatar(user)" :alt="fullName(user)">
<template v-if="userRoles.length">
<tr
v-for="({ user, ...item }, index) in userRoles"
:class="{ active: item.active ?? false }"
:key="index"
>
<th scope="row">{{ index + 1 }}</th>
<td>
<div class="user-info">
<div class="user-info-avatar">
<img :src="userAvatar(user)" :alt="fullName(user)" />
</div>
<div class="user-info-details">
<p class="name">
{{ fullName(user) }}
</p>
<p class="username">
@{{ user.username ?? "بدون نام کاربری" }}
</p>
</div>
</div>
<div class="user-info-details">
<p class="name">
{{ fullName(user) }}
</p>
<p class="username">
@{{ user.username ?? 'بدون نام کاربری' }}
</p>
</div>
</div>
</td>
<td><span>{{ item.role_name ?? '--' }}</span></td>
<td><span>از {{ convertUnixToPersianDateTime(item.created_at) }}</span></td>
<td>
<button @click="toggleRolesPanel(index)" title="ویرایش"
class="btn edit-btn"
data-bs-toggle="modal"
data-bs-target="#edit-paper">
<i class="tavasi tavasi-Component-242--1"></i>
</button>
<!-- <button @click="deleteItem(item.id)" title="حذف"-->
<!-- class="btn delete-btn"-->
<!-- type="button"-->
<!-- >-->
<!-- <img class="" src="@assets/common/img/Component 295 1.svg" alt="حذف"/>-->
<!-- </button>-->
</td>
</tr>
</template>
<table-no-data v-else></table-no-data>
</td>
<td>
<span>{{ item.role_name ?? "--" }}</span>
</td>
<td>
<span
>از
{{ convertUnixToPersianDateTime(item.created_at) }}</span
>
</td>
<td>
<button
@click="toggleRolesPanel(index)"
title="ویرایش"
class="btn edit-btn"
data-bs-toggle="modal"
data-bs-target="#edit-paper"
>
<i class="tavasi tavasi-Component-242--1"></i>
</button>
<!-- <button @click="deleteItem(item.id)" title="حذف"-->
<!-- class="btn delete-btn"-->
<!-- type="button"-->
<!-- >-->
<!-- <img class="" src="@assets/common/img/Component 295 1.svg" alt="حذف"/>-->
<!-- </button>-->
</td>
</tr>
</template>
<table-no-data v-else></table-no-data>
</tbody>
</table>
</div>
<div class="side-panel" v-if="showPanel">
<div class="side-panel-header">
<h6 class="">
مدیریت نقش ها
</h6>
<h6 class="">مدیریت نقش ها</h6>
</div>
<div class="side-panel-content ">
<div class="side-panel-content">
<!-- <div class="mb-5">-->
<!-- <label for="role_id">انتخاب بخش</label>-->
<!-- <select @change="getUserPermission()" name="role_id" id="role_id"-->
@ -133,20 +159,15 @@
<!-- </select>-->
<!-- </div>-->
<accordion
v-if="user_id"
:user_id="user_id"
></accordion>
<accordion v-if="user_id" :user_id="user_id"></accordion>
<div class="side-panel-footer mt-4">
<div>
</div>
<div></div>
<div>
<button
@click.prevent="showPanel = false"
type="button"
class="btn btn-primary"
data-dismiss="modal"
@click.prevent="showPanel = false"
type="button"
class="btn btn-primary"
data-dismiss="modal"
>
بستن
</button>
@ -161,29 +182,25 @@
</template>
<script>
import apis from "@permission/permitApi";
import {mapGetters} from "vuex";
import { mapGetters } from "vuex";
export default {
name:"UserAccessCustomization",
name: "UserAccessCustomization",
components: {
BreadCrumb: () =>
import( "@components/BreadCrumb.vue"),
Share: () =>
import( "@view/modal/Share.vue"),
Accordion: () =>
import( "@permission/components/Accordion.vue"),
BreadCrumb: () => import("@components/BreadCrumb.vue"),
Share: () => import("@view/modal/Share.vue"),
Accordion: () => import("@permission/components/Accordion.vue"),
},
computed: {
...mapGetters(["projectGetter"])
...mapGetters(["projectGetter"]),
},
props: {
items: {
default() {
return {}
}
}
return {};
},
},
},
data() {
return {
@ -205,8 +222,8 @@ export default {
editMode: false,
searchForm: {
query: '',
replaceWith: '',
query: "",
replaceWith: "",
wholeWord: false,
},
};
@ -217,30 +234,23 @@ export default {
},
fullName(user) {
if (user.name && user.lastname)
return user.name + ' ' + user.lastname;
else if (user.name && !user.lastname)
return user.name;
else if (!user.name && user.lastname)
return user.lastname;
return 'بدون نام';
},
deleteItem() {
if (user.name && user.lastname) return user.name + " " + user.lastname;
else if (user.name && !user.lastname) return user.name;
else if (!user.name && user.lastname) return user.lastname;
return "بدون نام";
},
deleteItem() {},
getUserRole() {
ApiService.formData(
apis.permissions.listUserRole,
{
project_id: this.projectGetter?.id
})
.then((response) => {
this.userRoles = response.data.data;
})
.catch((err) => {
})
.finally(() => {
this.loading = false;
})
ApiService.formData(apis.permissions.listUserRole, {
project_id: this.projectGetter?.id,
})
.then((response) => {
this.userRoles = response.data.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
save() {
@ -248,17 +258,19 @@ export default {
},
toggleRolesPanel(userRolesIndex = 0) {
this.getSections().then(res => {
this.getSections().then((res) => {
this.sections = res.data.data;
this.role_id = this.userRoles[userRolesIndex].role_id ?? undefined;
this.user_id = this.userRoles[userRolesIndex].user.id ?? undefined;
this.showPanel = true;
})
});
},
getSections() {
return ApiService.formData(apis.sections.list, {project_id: this.projectGetter?.id})
return ApiService.formData(apis.sections.list, {
project_id: this.projectGetter?.id,
});
},
collapseAllPanels() {
@ -277,7 +289,6 @@ export default {
this.typingTimer = setTimeout(() => {
this.highLight();
}, this.doneTypingInterval);
},
onKeyDown() {
clearTimeout(this.typingTimer);
@ -291,12 +302,9 @@ export default {
projectGetter() {
this.showPanel = false;
this.getUserRole();
}
}
}
},
},
};
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

View File

@ -166,7 +166,6 @@
import { useCommonStore } from "~/stores/commonStore";
import { mapState, mapActions } from "pinia";
import favoriteApi from "~/apis/favoriteApi";
import searchApi from "~/apis/searchApi";
import { useFavoriteStore } from "~/stores/favoriteStore";
import { useAuthStore } from "~/stores/authStore";
import { clearBodyClass } from "@manuals/utilities";
@ -369,7 +368,7 @@ export default {
async getSchemas() {
try {
const { $api } = useNuxtApp();
const res = await $api(searchApi.schema.list, {
const res = await $api(favoriteApi.schema.list, {
baseURL: import.meta.env.VITE_REPO_BASE_URL,
method: "POST",
body: {
@ -389,7 +388,7 @@ export default {
} catch (err) {}
// this.httpService
// .postRequest(searchApi.schema.list, {
// .postRequest(favoriteApi.schema.list, {
// organ: "public",
// system: "favorite",
// build_state: this.buildState(),

View File

@ -160,7 +160,6 @@
import { useCommonStore } from "~/stores/commonStore";
import { mapState, mapActions } from "pinia";
import favoriteApi from "~/apis/favoriteApi";
import searchApi from "~/apis/searchApi";
import { useFavoriteStore } from "~/stores/favoriteStore";
import { useAuthStore } from "~/stores/authStore";
import { clearBodyClass } from "@manuals/utilities";
@ -350,7 +349,7 @@ export default {
async getSchemas() {
try {
const { $api } = useNuxtApp();
const res = await $api(searchApi.schema.list, {
const res = await $api(favoriteApi.schema.list, {
baseURL: import.meta.env.VITE_REPO_BASE_URL,
method: "POST",
body: {
@ -370,7 +369,7 @@ export default {
} catch (err) {}
// this.httpService
// .postRequest(searchApi.schema.list, {
// .postRequest(favoriteApi.schema.list, {
// organ: "public",
// system: "favorite",
// build_state: buildState(),

View File

@ -102,7 +102,6 @@
<script>
import { mapActions, mapState } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
import { useEntityStore } from "~/stores/entityStore";
export default {
mounted() {
@ -145,12 +144,10 @@ export default {
};
},
computed: {
...mapState(useCommonStore, ["isShowHilightGetter"]),
...mapState(useEntityStore, ["diffTypeGetter"]),
...mapState(useCommonStore, ["isShowHilightGetter",'diffTypeGetter']),
},
methods: {
...mapActions(useCommonStore, ["isShowHilightSetter"]),
...mapActions(useEntityStore, ["diffTypeSetter"]),
...mapActions(useCommonStore, ["isShowHilightSetter","diffTypeSetter"]),
switchViewMode(viewMode) {
this.viewMode = viewMode;
if (viewMode == "show") this.isShowHilightSetter(true);

View File

@ -2,8 +2,7 @@ import { defineStore } from "pinia";
import { useAuthStore } from "./authStore";
import permitApis from "~/apis/permitApi";
import authApi from "~/apis/authApi";
import {useStorage} from "@vueuse/core";
import { useStorage } from "@vueuse/core";
import type {
JahatSection,
@ -21,11 +20,21 @@ import type {
Pagination,
} from "~/types/commonTypes";
import type { researchTerms } from "~/types/researchTypes";
import type { ActiveEntityViewSchema, ActiveTab } from "~/types/entityType";
export const useCommonStore = defineStore("commonStore", {
persist: {
storage: piniaPluginPersistedstate.localStorage()
storage: piniaPluginPersistedstate.localStorage(),
},
state: () => ({
diffType: undefined,
activeTab: undefined as ActiveTab | undefined,
activeEntityViewSchema: undefined as ActiveEntityViewSchema | undefined,
researchTerms: undefined as researchTerms | undefined,
count: 0 as number,
name: "" as string,
jahatSection: [] as JahatSection,
@ -73,6 +82,19 @@ export const useCommonStore = defineStore("commonStore", {
sidebarMenu: {},
}),
getters: {
diffTypeGetter(diffType) {
return diffType;
},
activeTabGetter(state) {
return state.activeTab;
},
activeEntityViewSchemaGetter(state) {
return state.activeEntityViewSchema;
},
researchTermsGetter(state) {
return state.researchTerms;
},
doubleCount: (state) => state.count * 2,
loginMicroServiceName: () => import.meta.env.VITE_AUTH,
messageMircroServiceName: () => import.meta.env.VITE_MESSAGE,
@ -114,6 +136,19 @@ export const useCommonStore = defineStore("commonStore", {
isShowHilightGetter: (state) => state.isShowHilight,
},
actions: {
diffTypeSetter(diffType) {
this.diffType = diffType;
},
activeTabSetter(activeTab = undefined) {
this.activeTab = activeTab;
},
activeEntityViewSchemaSetter(activeEntityViewSchema = undefined) {
this.activeEntityViewSchema = activeEntityViewSchema;
},
researchTermsSetter(researchTerms = undefined) {
this.researchTerms = researchTerms;
},
activeSchemaSetter(activeSchema: {}) {
if (this.activeSchema) this.activeSchema = activeSchema;
},
@ -318,7 +353,7 @@ export const useCommonStore = defineStore("commonStore", {
return await $fetch(permitApis.projects.list, {
baseURL: baseUrl + apiName + import.meta.env.VITE_PERMIT_BASE_URL,
headers: {
Authorization: useStorage('id_token','').value,
Authorization: useStorage("id_token", "").value,
},
method: "post",
})

1
systems/hadith_ui Submodule

@ -0,0 +1 @@
Subproject commit d1bab369112740397eadb89aa3439b713aafad64

1
systems/research_ui Submodule

@ -0,0 +1 @@
Subproject commit 702ffbc78224ad2bbce6832c9dbd537e3269e806

1
systems/search_ui Submodule

@ -0,0 +1 @@
Subproject commit e70f3d742249d7bc0ca196abe9c4a05303d01474

View File

@ -1,15 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./app.vue",
"./error.vue",
],
theme: {
extend: {},
},
plugins: [],
};

3736
yarn.lock

File diff suppressed because it is too large Load Diff