Compare commits
No commits in common. "c9fe6b38c54a577a64ce6e0a867bba9721ef3270" and "7de449e90c33b9ab41a0a2c23f33a55a108cefd4" have entirely different histories.
c9fe6b38c5
...
7de449e90c
|
|
@ -1,3 +1,4 @@
|
||||||
|
<!-- app.vue -->
|
||||||
<template>
|
<template>
|
||||||
<UApp>
|
<UApp>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
|
|
@ -10,7 +11,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useHead } from "#imports";
|
import { useHead } from "#imports";
|
||||||
import { onMounted } from "vue";
|
import { onMounted } from "vue";
|
||||||
import { composSystemTheme } from "@/composables/composSystemTheme";
|
import { composSystemTheme } from "~/composables/composSystemTheme";
|
||||||
// تنظیم تم سیستم
|
// تنظیم تم سیستم
|
||||||
useHead({
|
useHead({
|
||||||
script: [
|
script: [
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="col-span-3 lg:col-span-2 xl:col-span-3 hidden lg:block">
|
<div class="col-span-3 lg:col-span-2 xl:col-span-3 hidden lg:block">
|
||||||
<template v-if="headerSchema.breadcrumb">
|
<template v-if="headerSchema.breadcrumb">
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
:breadcrumbData="defaultSidebar.topMenu"
|
:breadcrumbData="[]"
|
||||||
:tabs="tabs"
|
:tabs="tabs"
|
||||||
:activeTabId="activeTabModel"
|
:activeTabId="activeTabModel"
|
||||||
/>
|
/>
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
<template v-if="headerSchema.logo">
|
<template v-if="headerSchema.logo">
|
||||||
<nuxt-link :to="{ name: 'DashboardBasePage' }">
|
<nuxt-link :to="{ name: 'DashboardBasePage' }">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<img :src="logoSrc" alt="" class="h-9 w-9" />
|
<img :src="useSystemTheme.logo.value" alt="" class="h-9 w-9" />
|
||||||
<div v-if="useSystemTheme.currentTheme.value" class="flex flex-col">
|
<div v-if="useSystemTheme.currentTheme.value" class="flex flex-col">
|
||||||
<span class="font-bold text-gray-900 dark:text-light-primary">
|
<span class="font-bold text-gray-900 dark:text-light-primary">
|
||||||
{{ useSystemTheme.currentTheme.value.title || "" }}
|
{{ useSystemTheme.currentTheme.value.title || "" }}
|
||||||
|
|
@ -29,8 +29,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-3 lg:col-span-2 xl:col-span-3 lg:hidden">
|
<div class="col-span-3 lg:col-span-2 xl:col-span-3 lg:hidden">
|
||||||
<button
|
<button
|
||||||
@click="commonStore.toggleSidebar"
|
@click="toggleSidebarMenu"
|
||||||
class="flex cursor-pointer items-center justify-center w-8 h-8 rounded-md text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-dark-primary-800 transition-colors duration-200"
|
class="flex items-center justify-center w-8 h-8 rounded-md text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-dark-primary-800 transition-colors duration-200"
|
||||||
aria-label="باز کردن منو"
|
aria-label="باز کردن منو"
|
||||||
>
|
>
|
||||||
<UIcon name="i-heroicons-bars-3" class="w-5 h-5" />
|
<UIcon name="i-heroicons-bars-3" class="w-5 h-5" />
|
||||||
|
|
@ -123,7 +123,6 @@
|
||||||
import { ref, computed, onMounted } from "vue";
|
import { ref, computed, onMounted } from "vue";
|
||||||
import headerItems from "@/json/header/header.json";
|
import headerItems from "@/json/header/header.json";
|
||||||
import { composSystemTheme } from "@/composables/composSystemTheme";
|
import { composSystemTheme } from "@/composables/composSystemTheme";
|
||||||
import defaultSidebar from "@/json/sidebar/dashboard.json";
|
|
||||||
import { useCommonStore } from "@/stores/commonStore";
|
import { useCommonStore } from "@/stores/commonStore";
|
||||||
import { useAuthStore } from "@/stores/authStore";
|
import { useAuthStore } from "@/stores/authStore";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
@ -145,7 +144,7 @@ const emit = defineEmits([
|
||||||
"tab-change",
|
"tab-change",
|
||||||
"user-menu-select",
|
"user-menu-select",
|
||||||
]);
|
]);
|
||||||
const logoSrc = ref("");
|
|
||||||
/* ---------------- ACTIVE TAB ---------------- */
|
/* ---------------- ACTIVE TAB ---------------- */
|
||||||
const activeTabModel = computed({
|
const activeTabModel = computed({
|
||||||
get: () => props.activeTab,
|
get: () => props.activeTab,
|
||||||
|
|
@ -198,6 +197,9 @@ const userMenuItems = computed(() =>
|
||||||
|
|
||||||
// const userAvatar = "https://api.dicebear.com/7.x/avataaars/svg?seed=admin";
|
// const userAvatar = "https://api.dicebear.com/7.x/avataaars/svg?seed=admin";
|
||||||
const isClient = ref(false);
|
const isClient = ref(false);
|
||||||
|
onMounted(() => {
|
||||||
|
isClient.value = true;
|
||||||
|
});
|
||||||
|
|
||||||
const userAvatar = computed(() => {
|
const userAvatar = computed(() => {
|
||||||
if (!process.client) return null;
|
if (!process.client) return null;
|
||||||
|
|
@ -235,14 +237,7 @@ const userInitial = computed(() => {
|
||||||
return "؟";
|
return "؟";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// function toggleSidebarMenu() {
|
function toggleSidebarMenu() {
|
||||||
// commonStore.isSidebarOpen();
|
commonStore.isSidebarOpen();
|
||||||
// }
|
}
|
||||||
onMounted(() => {
|
|
||||||
isClient.value = true;
|
|
||||||
useSystemTheme.applyTheme();
|
|
||||||
setTimeout(() => {
|
|
||||||
logoSrc.value = useSystemTheme.logo.value;
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -4,44 +4,41 @@
|
||||||
side="left"
|
side="left"
|
||||||
:collapsed="collapsed"
|
:collapsed="collapsed"
|
||||||
collapsible
|
collapsible
|
||||||
|
:min-size="5"
|
||||||
|
:default-size="10"
|
||||||
|
:max-size="15"
|
||||||
:ui="sidebarUI"
|
:ui="sidebarUI"
|
||||||
class="sidebar-gradient"
|
class="sidebar-gradient"
|
||||||
:style="{ width: collapsed ? '2%' : '8%' }"
|
|
||||||
dir="rtl"
|
dir="rtl"
|
||||||
@update:collapsed="onCollapse"
|
@update:collapsed="onCollapse"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<nuxt-link
|
<nuxt-link :to="{ name: 'DashboardBasePage' }">
|
||||||
:to="{ name: 'DashboardBasePage' }"
|
|
||||||
class="w-full flex justify-center items-center"
|
|
||||||
>
|
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<img :src="logoSrc" alt="" class="h-9 w-9" />
|
<img :src="useSystemTheme.logo.value" alt="" class="h-9 w-9" />
|
||||||
|
<div
|
||||||
|
v-if="useSystemTheme.currentTheme.value && !collapsed"
|
||||||
|
class="flex flex-col"
|
||||||
|
>
|
||||||
|
<span class="font-bold text-gray-900 dark:text-light-primary">
|
||||||
|
{{ useSystemTheme.currentTheme.value.title || "" }}
|
||||||
|
</span>
|
||||||
|
<span class="text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
{{ useSystemTheme.currentTheme.value.subTitle || "" }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- <div
|
|
||||||
v-if="useSystemTheme?.currentTheme?.value && !collapsed"
|
|
||||||
class="flex flex-col"
|
|
||||||
>
|
|
||||||
<span class="font-bold text-gray-900 dark:text-light-primary">
|
|
||||||
{{ useSystemTheme?.currentTheme?.value?.title || "" }}
|
|
||||||
</span>
|
|
||||||
<span class="text-xs text-gray-500 dark:text-gray-400">
|
|
||||||
{{ useSystemTheme?.currentTheme?.value?.subTitle || "" }}
|
|
||||||
</span>
|
|
||||||
</div> -->
|
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="">
|
<div class="">
|
||||||
|
|
||||||
<UNavigationMenu
|
<UNavigationMenu
|
||||||
dir="rtl"
|
dir="rtl"
|
||||||
orientation="vertical"
|
|
||||||
:items="getSideBarSchema()?.topMenu || []"
|
|
||||||
:collapsed="collapsed"
|
:collapsed="collapsed"
|
||||||
|
:items="getSideBarSchema()?.topMenu || []"
|
||||||
|
orientation="vertical"
|
||||||
:ui="navigationUI"
|
:ui="navigationUI"
|
||||||
class="w-full"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -53,36 +50,21 @@
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
:ui="navigationUI"
|
:ui="navigationUI"
|
||||||
/>
|
/>
|
||||||
<UTooltip
|
</div>
|
||||||
arrow
|
</template>
|
||||||
dir="rtl"
|
|
||||||
:text="user?.first_name + ' ' + user?.last_name"
|
<template #footer="{ collapsed }">
|
||||||
>
|
<div>
|
||||||
<UButton
|
<UButton
|
||||||
:avatar="
|
:avatar="{ src: '' }"
|
||||||
user?.avatar
|
:label="collapsed ? undefined : 'مدیرفنی سامانه'"
|
||||||
? { src: user?.avatar }
|
|
||||||
: {
|
|
||||||
label:
|
|
||||||
(user?.first_name?.[0] || '') +
|
|
||||||
(user?.last_name?.[0] || ''),
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:label="
|
|
||||||
collapsed ? '' : user?.first_name + ' ' + user?.last_name || ''
|
|
||||||
"
|
|
||||||
color="neutral"
|
color="neutral"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
:block="collapsed"
|
:block="collapsed"
|
||||||
/></UTooltip>
|
/>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<div>
|
|
||||||
<!-- دکمههای باز/بسته کردن سایدبار -->
|
<!-- دکمههای باز/بسته کردن سایدبار -->
|
||||||
<div class="flex justify-center items-center gap-2 mt-4">
|
<div class="flex justify-center items-center gap-2 mt-2">
|
||||||
<!-- دکمه باز کردن -->
|
<!-- دکمه باز کردن -->
|
||||||
<UButton
|
<UButton
|
||||||
v-if="collapsed"
|
v-if="collapsed"
|
||||||
|
|
@ -107,85 +89,12 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UDashboardSidebar>
|
</UDashboardSidebar>
|
||||||
<USlideover
|
|
||||||
v-model:open="sidebarOpenComputed"
|
|
||||||
side="right"
|
|
||||||
overlay
|
|
||||||
class="lg:hidden"
|
|
||||||
:dismissible="true"
|
|
||||||
dir="rtl"
|
|
||||||
:title="
|
|
||||||
useSystemTheme?.currentTheme?.value?.title +
|
|
||||||
' - ' +
|
|
||||||
useSystemTheme?.currentTheme?.value?.subTitle || ''
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<template #body>
|
|
||||||
<div class="p-4 flex flex-col h-full">
|
|
||||||
<UNavigationMenu
|
|
||||||
orientation="vertical"
|
|
||||||
:items="filteredSidebar.topMenu"
|
|
||||||
@click="onMenuSelect"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<UNavigationMenu
|
|
||||||
orientation="vertical"
|
|
||||||
:items="filteredSidebar.bottomMenu"
|
|
||||||
@click="onMenuSelect"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #footer="{ collapsed }">
|
|
||||||
<div>
|
|
||||||
<UButton
|
|
||||||
:avatar="
|
|
||||||
user?.avatar
|
|
||||||
? { src: user?.avatar }
|
|
||||||
: {
|
|
||||||
label:
|
|
||||||
(user?.first_name?.[0] || '') +
|
|
||||||
(user?.last_name?.[0] || ''),
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:label="
|
|
||||||
collapsed ? '' : user?.first_name + ' ' + user?.last_name || ''
|
|
||||||
"
|
|
||||||
color="neutral"
|
|
||||||
variant="ghost"
|
|
||||||
class="w-full"
|
|
||||||
:block="collapsed"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</USlideover>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from "vue";
|
import { ref} from "vue";
|
||||||
import { composSystemTheme } from "@/composables/composSystemTheme";
|
import { composSystemTheme } from "@/composables/composSystemTheme";
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import { useCommonStore } from "@/stores/commonStore";
|
|
||||||
|
|
||||||
const commonStore = useCommonStore();
|
|
||||||
const { sidebarOpen } = storeToRefs(commonStore);
|
|
||||||
|
|
||||||
// proxy امن برای v-model:open
|
|
||||||
const sidebarOpenComputed = computed({
|
|
||||||
get: () => sidebarOpen.value,
|
|
||||||
set: (v) => (commonStore.sidebarOpen = v),
|
|
||||||
});
|
|
||||||
const filteredSidebar = computed(
|
|
||||||
() => props.sidebarItems || { topMenu: [], bottomMenu: [] },
|
|
||||||
);
|
|
||||||
|
|
||||||
function onMenuSelect() {
|
|
||||||
// وقتی کاربر آیتم منو رو زد، اسلایداور رو ببند
|
|
||||||
commonStore.closeSidebar();
|
|
||||||
}
|
|
||||||
const useSystemTheme = composSystemTheme();
|
const useSystemTheme = composSystemTheme();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -201,35 +110,27 @@ const props = defineProps({
|
||||||
|
|
||||||
const emit = defineEmits(["update:collapsed"]);
|
const emit = defineEmits(["update:collapsed"]);
|
||||||
|
|
||||||
const logoSrc = ref("");
|
|
||||||
const collapsed = ref(false);
|
const collapsed = ref(false);
|
||||||
const user = ref({ first_name: "", last_name: "", avatar: "" });
|
|
||||||
const onCollapse = (value) => {
|
const onCollapse = (value) => {
|
||||||
collapsed.value = value;
|
collapsed.value = value;
|
||||||
emit("update:collapsed", value);
|
emit("update:collapsed", value);
|
||||||
};
|
};
|
||||||
function getSideBarSchema() {
|
|
||||||
|
function getSideBarSchema(){
|
||||||
|
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
const NUXT_PUBLIC_IS_DEVLOP_MODE = Number(
|
const IS_DEVLOP_MODE = config.public.IS_DEVLOP_MODE || 1;
|
||||||
config.public?.NUXT_PUBLIC_IS_DEVLOP_MODE ?? 1,
|
|
||||||
);
|
|
||||||
|
|
||||||
const filterMenu = (menu) => {
|
|
||||||
if (NUXT_PUBLIC_IS_DEVLOP_MODE === 1) return menu || [];
|
|
||||||
return (
|
|
||||||
menu?.filter(
|
|
||||||
(el) => el.develop === undefined || Number(el.develop) === 0,
|
|
||||||
) || []
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const topMenuFiltered = filterMenu(props.sidebarItems?.topMenu);
|
let result = {}
|
||||||
const bottomMenuFiltered = filterMenu(props.sidebarItems?.bottomMenu);
|
|
||||||
|
|
||||||
return {
|
result.topMenu = props.sidebarItems?.topMenu.filter((el) => (!el.develop || el.develop == IS_DEVLOP_MODE) )
|
||||||
topMenu: topMenuFiltered,
|
result.bottomMenu = props.sidebarItems?.bottomMenu.filter((el) => (!el.develop || el.develop == IS_DEVLOP_MODE) )
|
||||||
bottomMenu: bottomMenuFiltered,
|
|
||||||
};
|
// console.log("SideBar IS_DEVLOP_MODE ", IS_DEVLOP_MODE, result);
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// تابع برای باز/بسته کردن نرم سایدبار
|
// تابع برای باز/بسته کردن نرم سایدبار
|
||||||
|
|
@ -239,6 +140,8 @@ const toggleSidebar = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const sidebarUI = {
|
const sidebarUI = {
|
||||||
|
width: "w-72",
|
||||||
|
collapsed: { width: "w-16" },
|
||||||
wrapper:
|
wrapper:
|
||||||
"z-30 h-[calc(100vh-64px)] top-16 rounded-r-2xl border-r border-gray-200/50 dark:border-dark-primary-800/50 backdrop-blur-sm transition-all duration-300",
|
"z-30 h-[calc(100vh-64px)] top-16 rounded-r-2xl border-r border-gray-200/50 dark:border-dark-primary-800/50 backdrop-blur-sm transition-all duration-300",
|
||||||
base: "backdrop-blur-sm transition-all duration-300 ease-out",
|
base: "backdrop-blur-sm transition-all duration-300 ease-out",
|
||||||
|
|
@ -255,21 +158,6 @@ const navigationUI = {
|
||||||
"bg-gradient-to-r from-blue-100 to-blue-50/30 dark:from-blue-900/30 dark:to-blue-900/10 text-blue-600 dark:text-blue-400 font-semibold shadow-sm",
|
"bg-gradient-to-r from-blue-100 to-blue-50/30 dark:from-blue-900/30 dark:to-blue-900/10 text-blue-600 dark:text-blue-400 font-semibold shadow-sm",
|
||||||
icon: { base: "transition-transform duration-300", active: "scale-110" },
|
icon: { base: "transition-transform duration-300", active: "scale-110" },
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
useSystemTheme.applyTheme();
|
|
||||||
setTimeout(() => {
|
|
||||||
logoSrc.value = useSystemTheme.logo.value;
|
|
||||||
}, 300);
|
|
||||||
const stored = localStorage.getItem("user");
|
|
||||||
if (stored) {
|
|
||||||
try {
|
|
||||||
user.value = JSON.parse(stored);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("خطا در خواندن کاربر از localStorage:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,124 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- تولبار ادیتور -->
|
<!-- تولبار ادیتور -->
|
||||||
<div class="editor-toolbar" v-if="editor">
|
<div v-if="editor" class="editor-toolbar">
|
||||||
<div
|
<div class="toolbar-group">
|
||||||
class="toolbar-group"
|
|
||||||
v-for="(group, gIndex) in toolbarGroups"
|
|
||||||
:key="gIndex"
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
v-for="(btn, index) in group"
|
@click="editor.chain().focus().toggleBold().run()"
|
||||||
:key="index"
|
:class="{ 'is-active': editor.isActive('bold') }"
|
||||||
@click="btn.action(editor)"
|
title="بولد"
|
||||||
:class="{ 'is-active': btn.isActive ? btn.isActive(editor) : false }"
|
|
||||||
:disabled="btn.disabled ? !btn.disabled(editor) : false"
|
|
||||||
:title="btn.title"
|
|
||||||
>
|
>
|
||||||
<span class="toolbar-icon">{{ btn.icon }}</span>
|
<span class="toolbar-icon">𝐁</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleItalic().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('italic') }"
|
||||||
|
title="ایتالیک"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">𝐼</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleUnderline().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('underline') }"
|
||||||
|
title="زیرخط"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">𝑈</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleStrike().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('strike') }"
|
||||||
|
title="خط خورده"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">̶S̶</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleHeading({ level: 1 }).run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('heading', { level: 1 }) }"
|
||||||
|
title="عنوان ۱"
|
||||||
|
>
|
||||||
|
H1
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleHeading({ level: 2 }).run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('heading', { level: 2 }) }"
|
||||||
|
title="عنوان ۲"
|
||||||
|
>
|
||||||
|
H2
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleHeading({ level: 3 }).run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('heading', { level: 3 }) }"
|
||||||
|
title="عنوان ۳"
|
||||||
|
>
|
||||||
|
H3
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleBulletList().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('bulletList') }"
|
||||||
|
title="لیست بولتدار"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">•</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleOrderedList().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('orderedList') }"
|
||||||
|
title="لیست شمارهدار"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">1.</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleBlockquote().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('blockquote') }"
|
||||||
|
title="نقل قول"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">"</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleCodeBlock().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('codeBlock') }"
|
||||||
|
title="کد"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">{ }</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().setDetails().run()"
|
||||||
|
:disabled="!editor.can().setDetails()"
|
||||||
|
title="افزودن جزییات"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">📋</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().unsetDetails().run()"
|
||||||
|
:disabled="!editor.can().unsetDetails()"
|
||||||
|
title="حذف جزییات"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">🗑️</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().undo().run()"
|
||||||
|
:disabled="!editor.can().undo()"
|
||||||
|
title="بازگشت"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">↩</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().redo().run()"
|
||||||
|
:disabled="!editor.can().redo()"
|
||||||
|
title="جلو"
|
||||||
|
>
|
||||||
|
<span class="toolbar-icon">↪</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -55,116 +158,6 @@ function isList(text) {
|
||||||
/^\d+\./.test(line.trim()),
|
/^\d+\./.test(line.trim()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const toolbarGroups = [
|
|
||||||
// گروه فرمت متن
|
|
||||||
[
|
|
||||||
{
|
|
||||||
title: "بولد",
|
|
||||||
icon: "𝐁",
|
|
||||||
action: (editor) => editor.chain().focus().toggleBold().run(),
|
|
||||||
isActive: (editor) => editor.isActive("bold"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "ایتالیک",
|
|
||||||
icon: "𝐼",
|
|
||||||
action: (editor) => editor.chain().focus().toggleItalic().run(),
|
|
||||||
isActive: (editor) => editor.isActive("italic"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "زیرخط",
|
|
||||||
icon: "𝑈",
|
|
||||||
action: (editor) => editor.chain().focus().toggleUnderline().run(),
|
|
||||||
isActive: (editor) => editor.isActive("underline"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "خط خورده",
|
|
||||||
icon: "̶S̶",
|
|
||||||
action: (editor) => editor.chain().focus().toggleStrike().run(),
|
|
||||||
isActive: (editor) => editor.isActive("strike"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// گروه هدینگها
|
|
||||||
[
|
|
||||||
{
|
|
||||||
title: "عنوان ۱",
|
|
||||||
icon: "H1",
|
|
||||||
action: (editor) =>
|
|
||||||
editor.chain().focus().toggleHeading({ level: 1 }).run(),
|
|
||||||
isActive: (editor) => editor.isActive("heading", { level: 1 }),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "عنوان ۲",
|
|
||||||
icon: "H2",
|
|
||||||
action: (editor) =>
|
|
||||||
editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
||||||
isActive: (editor) => editor.isActive("heading", { level: 2 }),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "عنوان ۳",
|
|
||||||
icon: "H3",
|
|
||||||
action: (editor) =>
|
|
||||||
editor.chain().focus().toggleHeading({ level: 3 }).run(),
|
|
||||||
isActive: (editor) => editor.isActive("heading", { level: 3 }),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// گروه لیست و نقل قول
|
|
||||||
[
|
|
||||||
{
|
|
||||||
title: "لیست بولتدار",
|
|
||||||
icon: "•",
|
|
||||||
action: (editor) => editor.chain().focus().toggleBulletList().run(),
|
|
||||||
isActive: (editor) => editor.isActive("bulletList"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "لیست شمارهدار",
|
|
||||||
icon: "1.",
|
|
||||||
action: (editor) => editor.chain().focus().toggleOrderedList().run(),
|
|
||||||
isActive: (editor) => editor.isActive("orderedList"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "نقل قول",
|
|
||||||
icon: '"',
|
|
||||||
action: (editor) => editor.chain().focus().toggleBlockquote().run(),
|
|
||||||
isActive: (editor) => editor.isActive("blockquote"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "کد",
|
|
||||||
icon: "{ }",
|
|
||||||
action: (editor) => editor.chain().focus().toggleCodeBlock().run(),
|
|
||||||
isActive: (editor) => editor.isActive("codeBlock"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// گروه جزییات
|
|
||||||
[
|
|
||||||
{
|
|
||||||
title: "افزودن جزییات",
|
|
||||||
icon: "📋",
|
|
||||||
action: (editor) => editor.chain().focus().setDetails().run(),
|
|
||||||
disabled: (editor) => !editor.can().setDetails(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "حذف جزییات",
|
|
||||||
icon: "🗑️",
|
|
||||||
action: (editor) => editor.chain().focus().unsetDetails().run(),
|
|
||||||
disabled: (editor) => !editor.can().unsetDetails(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// گروه Undo/Redo
|
|
||||||
[
|
|
||||||
{
|
|
||||||
title: "بازگشت",
|
|
||||||
icon: "↩",
|
|
||||||
action: (editor) => editor.chain().focus().undo().run(),
|
|
||||||
disabled: (editor) => !editor.can().undo(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "جلو",
|
|
||||||
icon: "↪",
|
|
||||||
action: (editor) => editor.chain().focus().redo().run(),
|
|
||||||
disabled: (editor) => !editor.can().redo(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
function formatListToHtml(text) {
|
function formatListToHtml(text) {
|
||||||
const lines = text.split("\n").filter((line) => line.trim() !== "");
|
const lines = text.split("\n").filter((line) => line.trim() !== "");
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@
|
||||||
"icon": "i-lucide-list",
|
"icon": "i-lucide-list",
|
||||||
"active": true
|
"active": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "RuleEdit",
|
||||||
|
"label": "احکام",
|
||||||
|
"key": "RuleEdit",
|
||||||
|
"icon": "i-lucide-scroll-text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "RelationEdit",
|
"id": "RelationEdit",
|
||||||
"key": "RelationEdit",
|
"key": "RelationEdit",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user