تغییرات

This commit is contained in:
Mehdi104797 2025-02-20 09:52:41 +03:30
parent 8b62a81b94
commit 221b4f1b32
50 changed files with 4575 additions and 3372 deletions

View File

@ -0,0 +1,276 @@
<template>
<div>
<div class="mb-5">
<select
name="project_id"
id="project_id"
v-model="project_id"
class="form-control text__14"
>
<option class="text-black-50" disabled :value="undefined" selected>
{{ $t("ProjectSelection") }}
</option>
<option
v-for="(project, index1) in projects"
:key="index1"
:value="project.id"
>
{{ project.title }}
</option>
</select>
</div>
<div class="accordion" id="permission-accordion">
<div
v-for="(item, key, index) in groupbyList"
:key="index"
class="card border-0"
>
<div class="card-header border-bottom-0 p-0" :id="'heading' + index">
<button
class="btn btn-link btn-block has-indicator"
type="button"
data-bs-toggle="collapse"
:data-bs-target="'#collapse' + index"
:aria-expanded="!collapseAll"
:class="{ collapsed: collapseAll }"
:aria-controls="'collapse' + index"
>
{{ key }}
</button>
</div>
<div
:id="'collapse' + index"
class="collapse"
:class="{ show: !collapseAll }"
:aria-labelledby="'heading' + index"
data-parent="#permission-accordion"
>
<div class="card-body">
<ul class="list-group list-group-flush">
<li
:key="index"
v-for="(action, index2) in groupItems(key)"
class="list-group-item text__14"
>
<div class="form-check d-flex align-items-center">
<input
v-can.checkbox="canEdit"
@change.prevent="changePermission(action)"
class="form-check-input"
type="checkbox"
value=""
:checked="action.check"
:value="action.check"
:id="'role-' + index2"
/>
<label class="form-check-label mt-2" :for="'role-' + index">
{{ action.action_title }}
</label>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import apis from "~/apis/permitApi";
// import { mapGetters, mapMutations, mapActions } from "vuex";
import { mapActions, mapState } from "pinia";
import { usePermitStore } from "~/stores/permitStore";
export default {
props: {
user_id: {
type: Number,
default: undefined,
},
role_id: {
type: Number,
default: undefined,
},
canEdit: {
type: String,
default(val) {},
},
},
data() {
return {
listUserPermission: [],
collapseAll: false,
grouplist: [],
groupbyList: {},
roles: [],
httpService: {},
};
},
computed: {
// ...mapGetters("permit", ["projectsGetter", "projectGetter"]),
...mapState(usePermitStore, ["projectGetter", "projectsGetter"]),
projects() {
return this.projectsGetter ?? [];
},
project_id: {
get() {
return this.projectGetter?.id;
},
set(newVal) {
this.setProject(newVal);
},
},
},
mounted() {
this.getRoles();
},
created() {
this.httpService = useNuxtApp()["$http"];
},
methods: {
// ...mapMutations("permit", ["SET_PROJECT"]),
// ...mapActions("permit", ["getProjects"]),
...mapActions(usePermitStore, ["SET_PROJECT"]),
...mapActions(usePermitStore, ["getProjects"]),
getRoles() {
const payload = {
user_id: this.user_id,
role_id: this.role_id,
project_id: this.projectGetter?.id,
};
const { listUserPermission, listRolePermission } = apis.permissions;
const url = this.user_id ? listUserPermission : listRolePermission;
this.httpService.postRequest(permitUrl() + url, payload).then(({ data }) => {
this.listUserPermission = data;
this.groupbyList = this.groupBy(data, "section_title");
});
},
toggleRolesPanel() {},
groupBy(arrayToGroup, key) {
return arrayToGroup.reduce(function (previousValue, currentValue) {
(previousValue[currentValue[key]] =
previousValue[currentValue[key]] || []).push({
action_title: currentValue.action_title,
check: currentValue.check,
section_title: currentValue.section_title,
section_id: currentValue.id,
section_user_id: currentValue?.section_user_id,
section_role_id: currentValue?.section_role_id,
});
return previousValue;
}, {});
},
groupItems(section_title) {
return this.groupbyList[section_title];
},
changePermission(action) {
action.check
? this.deletePermission(action)
: this.addOrUpdatePermission(action);
},
addOrUpdatePermission(action) {
const payload = {
user_id: this.user_id,
role_id: this.role_id,
project_id: this.projectGetter?.id,
section_id: action.section_id,
state: 0,
section_user_id: action.section_user_id ?? undefined,
section_role_id: action.section_role_id ?? undefined,
};
const {
addOrEditUserPermission,
addOrEditRolePermission,
addOrEditLoginRolePermission,
} = apis.permissions;
let url = this.user_id
? addOrEditUserPermission
: addOrEditRolePermission;
// حالت دسترسی تشویقی
if (this.role_id === -1) url = addOrEditLoginRolePermission;
this.httpService.postRequest(url, payload).then(({ data }) => {
mySwalToast({
title: "تبریک",
html: data.message,
icon: "success",
});
this.getRoles();
// action.check = true;
});
},
deletePermission(action) {
const payload = {
project_id: this.projectGetter?.id,
id: action.section_user_id ?? undefined,
};
if (action.section_role_id) payload.id = action.section_role_id;
const { deleteUserPermission, deleteRolePermission } = apis.permissions;
const url = this.user_id ? deleteUserPermission : deleteRolePermission;
this.httpService.postRequest(url, payload).then(({ data }) => {
mySwalToast({
title: "تبریک",
html: data.message,
icon: "success",
});
this.getRoles();
// action.check = false;
});
},
async getProjects() {
return await this.httpService
.postRequest(permitUrl() + apis.projects.list)
.then((res) => {
this.SET_PROJECT(res.data[0]);
});
},
setProject(id) {
// const id = +$ev.target.value;
const result = this.projects.findIndex((item) => item.id === id);
const project = this.projects[result];
this.SET_PROJECT(project);
this.getRoles();
},
},
watch: {
role_id() {
this.getRoles();
},
user_id() {
this.getRoles();
},
},
};
</script>
<style lang="scss" scoped>
.role-permission {
.form-check {
padding-right: 0;
}
.form-check-input {
margin-left: 1em;
margin-top: 0em !important;
&::before {
content: "";
right: unset;
top: unset;
}
}
}
</style>

View File

@ -9,7 +9,7 @@
<ul class="list-unstyled components">
<li class="active">
<a href="#homeSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle">
<a href="#homeSubmenu" data-bs-toggle="collapse" aria-expanded="false" class="dropdown-toggle">
<i class="fas fa-home"></i>
Home
</a>
@ -30,7 +30,7 @@
<i class="fas fa-briefcase"></i>
About
</a>
<a href="#pageSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle">
<a href="#pageSubmenu" data-bs-toggle="collapse" aria-expanded="false" class="dropdown-toggle">
<i class="fas fa-copy"></i>
Pages
</a>

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

@ -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,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 "@forms/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 "@forms/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

@ -39,7 +39,7 @@
<!-- <button
class="btn dropdown-toggle"
type="button"
data-toggle="dropdown"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
@ -69,7 +69,7 @@
<!-- <button
@click.prevent="showSearchs()"
type="button"
class="btn close-search p-0 pr-1"
class="btn close-search p-0 pe-1"
>
<svg class="icon icon-Component-71--1">
<use xlink:href="#icon-Component-71--1"></use>

View File

@ -10,7 +10,7 @@
class="form-control"
id="title"
name="title"
v-model="form?._source.title"
v-model="form._source.title"
/>
</div>
@ -75,12 +75,18 @@
<div class="form-group">
<label for="title">متن</label>
<my-quill
<!-- <my-quill
ref="quill-editor"
:parentButtonLoading="buttonLoading"
:tinyText="form?._source.description"
:showSaveButton="false"
></my-quill>
></my-quill> -->
<quill-editor
ref="quill-editor"
v-model="form._source.description"
content-type="html"
:options="editorOptions"
></quill-editor>
</div>
<div class="form-group d-flex">
@ -142,6 +148,9 @@ export default {
mounted() {
if (this.formData) this.form = this.formData;
},
created() {
this.httpService = useNuxtApp()["$http"];
},
computed: {
imageBaseUrl() {
return import.meta.env.VITE_BASE_URL;
@ -181,9 +190,26 @@ export default {
time_edit: 1111111111,
},
},
httpService: {},
hasImage: false,
imageUrl: undefined,
uploading: false,
editorOptions: {
theme: "snow", // تم ویرایشگر: 'snow' یا 'bubble'
placeholder: "متن خود را بنویسید...",
modules: {
toolbar: [
[{ header: [1, 2, 3, false] }], // سطح هدینگها
["bold", "italic", "underline", "strike"], // دکمههای استایل متن
[{ color: [] }, { background: [] }], // رنگ متن و پسزمینه
[{ list: "ordered" }, { list: "bullet" }], // لیستهای شمارهدار و نقطهای
["blockquote", "code-block"], // نقلقول و کد
[{ align: [] }], // تراز بندی متن
["link", "image", "video"], // افزودن لینک، تصویر، و ویدیو
["clean"], // حذف فرمتها
],
},
},
};
},
computed: {
@ -265,7 +291,7 @@ export default {
.then((res) => {
this.$emit("close-modal", true);
this.mySwalToast({
mySwalToast({
title: "تبریک",
html: res.message,
icon: "success",
@ -277,7 +303,7 @@ export default {
});
},
onDeleteItem(item) {
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
@ -289,7 +315,6 @@ export default {
});
},
},
};
</script>
<style lang="scss">

View File

@ -0,0 +1,664 @@
<template>
<!-- <div class="modal-dialog"> -->
<div class="modal-content">
<div class="popUp-tab__content tab-content share-modal__content">
<div class="share-modal__search-content">
<div class="share-modal__content">
<div class="share-modal__search">
<span>با </span>
<input
type="text"
placeholder="نام کاربر یا email@exaple.com"
id="searchForName"
v-model="query"
@keyup="showSearchResult"
/>
</div>
<div
id="user-search-recommend"
class="share-modal__search-recommend"
:class="{ show: suggestionMode }"
>
<div class="search-recommend">
<div
class="search-users__item d-flex justify-content-between align-items-center mx-2"
v-for="(user, i) in userSuggestions"
:key="'h' + i"
>
<div class="search-users__pic">
<img :src="userAvatar(user)" alt="" />
</div>
<div class="search-users__content">
<div class="search-users__name">
{{ user.full_name }}
</div>
<div class="search-users__id">@{{ user.username }}</div>
</div>
<div class="search-users__type">
<div class="order-select main-page__date-select">
<select
@change="addUser($event, user)"
class="form-control d-block"
>
<option selected disabled :value="undefined">
انتخاب نقش
</option>
<option
v-for="role in roles"
:key="role.id"
:value="role.id"
>
{{ role.title }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- </div> -->
</template>
<script>
// import HttpService from "@services/httpService";
export default {
name: "sharemodal",
props: ["item", "itemType", "roles"],
mounted() {
// this.httpService = new HttpService();
this.httpService = useNuxtApp()["$http"];
},
data() {
return {
httpService: {},
newItemType: 0,
suggestionMode: false,
query: "",
userSuggestions: [],
userToAdd: [],
};
},
methods: {
// formData(url, data = []) {
// const formData = new FormData();
// for (const [key, value] of Object.entries(data)) {
// if (value !== undefined && value !== null) formData.append(key, value);
// }
// return axios.post(url, formData);
// },
showSearchResult() {
var vm = this;
let url = loginUrl() + "user/suggestion";
if (this.query.length > 2) {
this.httpService
.postRequest(url, { query: this.query })
.then((response) => {
var items = response.data;
vm.userSuggestions = items;
vm.suggestionMode = true;
});
} else {
vm.userSuggestions = [];
vm.suggestionMode = false;
}
},
deleteUser: function (index) {
this.userToAdd.splice(index, 1);
},
addUser(ev, item) {
this.userToAdd.push(item);
this.suggestionMode = false;
this.$emit("update-user-role", {
user_id: item.user_id,
role_id: +ev.target.value,
});
// this.addPerm(ev, item);
},
addPerm(ev, item) {
// var guid = this.item.guid;
// this.userToAdd.forEach(function (item) {
// ApiService.post(this, "perm/set", {
// pid: guid,
// act: "add",
// read: 1,
// write: 0,
// username: item.username,
// });
// });
},
},
};
</script>
<style lang="scss">
@import "../../../assets/permit/scss/permit.scss";
</style>
<style scoped lang="scss">
.share-modal {
height: 20em;
background-color: #fff;
top: 7em;
left: 2em;
}
.search-users__pic {
display: flex;
margin-left: 15px;
position: relative;
img {
width: 32px;
height: 32px;
border-radius: 50%;
overflow: hidden;
}
}
.share-modal__content{
width: 100%;
}
.share-modal__search-top {
background-color: #eee;
padding-bottom: 1em;
font-size: 15px;
font-weight: 500;
}
.share-modal__search-recommend {
opacity: 1;
display: block;
position: static;
visibility: visible;
height: calc(100% - 12.5em);
overflow: auto;
/* display: none; */
/* opacity: unset; */
/* visibility: hidden; */
/* top: 117px; */
/* right: 0px; */
/* width: 100%; */
/* background: white; */
/* -webkit-transition: all 0.3s ease-in-out; */
/* transition: all 0.3s ease-in-out; */
/* opacity: 0; */
/* visibility: hidden; */
/* display: none; */
/* z-index: 10; */
&.show {
position: static !important;
opacity: 1 !important;
display: block !important;
visibility: visible !important;
}
}
// .share-modal {
// width: 337px;
// height: 385px;
// background-color: #fff;
// border: 1px solid #bac4ce;
// border-radius: 20px;
// top: 63px;
// left: 253px;
// transform: unset;
// &__modal {
// .modal-dialog {
// transform: unset !important;
// transition: unset !important;
// }
// }
// &__content {
// position: relative;
// width: 337px;
// height: 385px;
// display: flex;
// flex-direction: column;
// }
// &__search-content {
// position: absolute;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// transition: all 0.3s ease-in-out;
// }
// &__search {
// border-bottom: 1px solid #f1f1f1;
// display: flex;
// align-items: center;
// padding-top: 15px;
// padding-bottom: 15px;
// span {
// font-size: 16px;
// // color: var(--color-2);
// width: 50px;
// display: flex;
// justify-content: center;
// i {
// cursor: pointer;
// color: #92a2b2;
// font-size: 24px;
// width: 70px;
// display: flex;
// justify-content: center;
// align-items: center;
// }
// }
// #get-back {
// width: 70px;
// }
// input {
// flex-grow: 2;
// border: unset;
// outline: unset;
// // color: var(--color-2);
// font-size: 14px;
// &::placeholder {
// color: #92a2b2;
// font-size: 14px;
// }
// }
// }
// &__add-person {
// width: 50px;
// display: flex;
// justify-content: center;
// i {
// font-size: 24px;
// -webkit-transition: all 0.5s ease-in-out;
// transition: all 0.5s ease-in-out;
// font-size: 23px;
// background: -webkit-linear-gradient(#a9bdc4 0%, #c6cfda 100%);
// background-clip: border-box;
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
// }
// &:hover {
// i {
// background: -webkit-linear-gradient(#00b6e3 0%, #81e6ff 100%);
// background-clip: border-box;
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
// }
// }
// }
// &__search-recommend {
// display: none;
// opacity: unset;
// visibility: hidden;
// position: absolute;
// top: 57px;
// right: 0px;
// width: 100%;
// height: calc(100% - 57px);
// background: white;
// transition: all 0.3s ease-in-out;
// opacity: 0;
// visibility: hidden;
// display: none;
// z-index: 10;
// .os-host {
// height: 100%;
// }
// .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
// bottom: 0;
// right: 7px;
// top: 17px;
// width: 0px;
// }
// .os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
// background: rgba(0, 0, 0, 0.16);
// }
// }
// &__users {
// flex-grow: 1;
// max-height: 259px;
// .os-scrollbar-vertical {
// width: 0;
// }
// }
// &__icon {
// display: flex;
// justify-content: center;
// align-items: center;
// margin-bottom: 18px;
// img {
// width: 142px;
// padding-top: 42px;
// }
// }
// &__text {
// color: #92a2b2;
// font-size: 14px;
// padding-bottom: 37px;
// width: 246px;
// text-align: center;
// margin-right: auto;
// margin-left: auto;
// }
// &__search-content-footer {
// display: flex;
// align-items: flex-end;
// justify-content: space-between;
// padding-top: 15px;
// padding-bottom: 15px;
// border-top: 1px solid #bac4ce;
// padding-right: 22px;
// padding-left: 22px;
// }
// &__sign {
// display: flex;
// flex-direction: column;
// span {
// font-size: 12px;
// color: #92a2b2;
// display: block;
// margin-bottom: 2px;
// }
// a {
// // color: var(--color-1);
// font-size: 12px;
// }
// }
// &__settings {
// a {
// }
// }
// &__settings-btn {
// font-size: 14px;
// // color: var(--color-1);
// }
// &__settings-content {
// position: absolute;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// transition: all 0.3s ease-in-out;
// opacity: 0;
// visibility: hidden;
// display: none;
// }
// &__title {
// padding-top: 15px;
// padding-bottom: 15px;
// border-bottom: 1px solid #f1f1f1;
// padding-right: 22px;
// padding-left: 22px;
// h4 {
// font-size: 16px;
// }
// }
// &__form {
// padding-right: 22px;
// padding-left: 22px;
// &-question {
// font-size: 14px;
// font-weight: 500;
// text-shadow: 0 -0.75px #6b6b6b;
// margin-bottom: 17px;
// color: #444444;
// }
// &-item {
// padding-top: 17px;
// &:last-child {
// margin-bottom: 17px;
// }
// }
// &-radio-item {
// display: flex;
// align-items: center;
// &:not(:last-child) {
// margin-bottom: 20px;
// }
// input {
// }
// label {
// color: #444444;
// font-size: 14px;
// margin-right: 16px;
// margin-bottom: 0;
// }
// }
// &-btn {
// min-width: 57px;
// height: 32px;
// border-radius: 20px;
// display: flex;
// justify-content: center;
// align-items: center;
// margin-right: 10px;
// }
// &-radio {
// position: relative;
// input {
// position: absolute;
// opacity: 0;
// cursor: pointer;
// height: 20px;
// width: 20px;
// z-index: 5;
// }
// span {
// display: flex;
// height: 20px;
// width: 20px;
// border-radius: 50%;
// border: 2px solid #bac4ce;
// transition: all 0.3s ease-in-out;
// display: flex;
// justify-content: center;
// align-items: center;
// &::before {
// content: " ";
// width: 10px;
// height: 10px;
// border-radius: 50%;
// display: flex;
// background: linear-gradient(#3def90 0%, #1ed975 100%);
// opacity: 0;
// transition: all 0.3s ease-in-out;
// }
// }
// input:checked ~ span::before {
// opacity: 1;
// }
// }
// }
// &__form-btn--deactive {
// font-size: 14px;
// // color: var(--color-2);
// &:hover {
// opacity: 0.8;
// }
// }
// &__from-btn--active {
// // border: 2px solid var(--color-1);
// // color: var(--color-1);
// font-size: 14px;
// &:hover {
// color: white;
// // background: var(--color-1);
// }
// }
// &__setting-footer {
// margin-top: auto;
// border-top: 1px solid #f1f1f1;
// display: flex;
// align-items: center;
// justify-content: flex-end;
// padding: 16px;
// }
// &__people-search {
// background: #fff;
// position: absolute;
// top: 0;
// display: none;
// left: 0;
// width: 100%;
// height: 100%;
// transition: all 0.3s ease-in-out;
// opacity: 0;
// visibility: hidden;
// .os-host {
// height: 100%;
// }
// .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
// bottom: 0;
// right: 7px;
// top: 17px;
// width: 0px;
// }
// .os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
// background: rgba(0, 0, 0, 0.16);
// }
// }
// &__user-search-content {
// opacity: unset;
// width: 100%;
// height: calc(100% - 57px);
// background: white;
// transition: all 0.3s ease-in-out;
// top: 57px;
// display: none;
// .os-host {
// height: 100%;
// }
// .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
// bottom: 0;
// right: 7px;
// top: 17px;
// width: 0px;
// }
// .os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
// background: rgba(0, 0, 0, 0.16);
// }
// }
// &__users-footer {
// display: flex;
// flex-direction: column;
// }
// &__textarea {
// border-top: 1px solid #f1f1f1;
// padding-top: 12px;
// padding-bottom: 12px;
// padding-right: 22px;
// padding-left: 22px;
// }
// &__invite-row {
// border-top: 1px solid #f1f1f1;
// display: flex;
// align-items: center;
// padding-top: 17.5px;
// padding-bottom: 26px;
// justify-content: space-between;
// padding-right: 22px;
// padding-left: 22px;
// }
// &__select {
// font-size: 14px;
// .main-page__date-select .select-selected {
// border: unset;
// padding: 0;
// }
// .main-page__date-select .select-selected {
// height: 32px;
// }
// .select-items {
// width: 160px;
// }
// .main-page__date-select .select-items {
// top: unset;
// bottom: calc(5px + 100%);
// }
// }
// &__send-invite {
// a {
// display: flex;
// justify-content: center;
// align-items: center;
// min-width: 120px;
// border-radius: 20px;
// // border: 2px solid var(--color-1);
// height: 32px;
// font-size: 14px;
// &:hover {
// color: white;
// // background: var(--color-1);
// }
// }
// }
// }
</style>

View File

@ -271,7 +271,7 @@ export default {
</script>
<style lang="scss">
@import "../assets/majles/scss/majles";
@import "../../../assets/majles/scss/majles";
.custom-class {
.dropdown-toggle {

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

@ -0,0 +1,72 @@
[
{
"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": ""
},
{
"showOutside": false,
"show": true,
"icon": "default",
"title": "ویرایش",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "edit-btn",
"action": "edit-table-item",
"can": ""
},
{
"showOutside": false,
"show": true,
"icon": "default",
"title": "حذف",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "delete-btn",
"action": "delete-table-item",
"can": ""
},
{
"showOutside": false,
"show": true,
"icon": "default",
"title": "ستون های فهرست",
"to": {
"name": "undefined"
},
"selected": false,
"disabled": false,
"howToOpen": "",
"href": "",
"class": "",
"action": "select-list-columns",
"can": ""
}
]

View File

@ -14,6 +14,174 @@
"link": "admin",
"title": "پیشخوان مدیر",
"translateKey": "AdminDashboard"
},
{
"color": 2,
"icon": "settings",
"link": "dataSettingAboutUs",
"title": "تنظیمات",
"translateKey": "Settings",
"subMenu": [
{
"color": 2,
"icon": "profile",
"link": "dataSettingAboutUs",
"title": "متن در باره ما",
"translateKey": "AboutUsText"
},
{
"color": 2,
"icon": "contact",
"link": "dataSettingContactUs",
"title": "متن تماس با ما",
"translateKey": "ContactUsText"
},
{
"color": 2,
"icon": "Component-295--1",
"link": "stopWord",
"title": "کلمات حذفی",
"translateKey": "DeletedWords"
},
{
"color": 2,
"icon": "search-iconldpi",
"link": "searchAmplify",
"title": "جستجوی مفهومی",
"translateKey": "ConceptualSearch"
},
{
"color": 2,
"icon": "Component-285--2",
"link": "adminNotifications",
"title": "اعلانات",
"translateKey": "Notifications"
}
]
},
{
"color": 3,
"icon": "access",
"link": "sections",
"title": "دسترسی",
"translateKey": "Access",
"subMenu": [
{
"icon": "panel-sectioned",
"color": 3,
"link": "sections",
"title": "بخش ها",
"translateKey": "Sections"
},
{
"icon": "portal-roles",
"color": 3,
"link": "Roles",
"title": "نقش ها",
"translateKey": "Roles"
},
{
"icon": "access",
"color": 3,
"link": "rolePermission",
"title": "دسترسی نقش",
"translateKey": "RoleAccess"
},
{
"icon": "user-role",
"color": 3,
"link": "UserPermission",
"title": "نقش کاربر",
"translateKey": "UserRole"
}
]
},
{
"color": 3,
"icon": "Group-7932",
"link": "adminUsers",
"title": "مدیریت ",
"translateKey": "Management",
"subMenu": [
{
"color": 3,
"icon": "Component-259--1",
"link": "adminUsers",
"title": "کاربران",
"translateKey": "Users"
},
{
"color": 3,
"icon": "Component-259--1",
"link": "userModifications",
"title": " اصلاحیات کاربران",
"translateKey": "UserModifications"
},
{
"color": 3,
"icon": "groups",
"link": "groupsWithoutAdmin",
"title": " گروه های آزاد",
"translateKey": "FreeGroups"
}
]
},
{
"color": 3,
"icon": "doc-outline",
"link": "formList",
"title": "فرم ها",
"translateKey": "forms",
"subMenu": [
{
"icon": "doc-outline",
"color": 3,
"link": "formList",
"title": "فرم ها",
"translateKey": "forms"
},
{
"icon": "folder-plus",
"color": 3,
"link": "newForm",
"title": "فرم جدید",
"translateKey": "NewForm"
},
{
"icon": "Component-68--1",
"color": 3,
"link": "selectListColumnsCreate",
"title": "انتخاب ستون های فهرست",
"translateKey": "SelectColumnsOfList"
}
]
},
{
"color": 2,
"icon": "question",
"link": "adminGuides",
"title": " راهنما",
"translateKey": "Help",
"subMenu": [
{
"color": 2,
"icon": "Component-220--11",
"link": "adminGuides",
"title": "جدید",
"translateKey": "New"
},
{
"color": 2,
"icon": "Component-68--1",
"link": "guidesList",
"title": "فهرست ",
"translateKey": "Contents"
}
]
}
]
}
}

View File

@ -0,0 +1,37 @@
[
{
"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": ""
}
]

476
package-lock.json generated
View File

@ -14,6 +14,7 @@
"@popperjs/core": "^2.11.8",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"@vueup/vue-quill": "^1.2.0",
"axios": "^1.7.7",
"bootstrap": "^5.3.3",
"docx": "^9.1.1",
@ -5300,6 +5301,19 @@
}
}
},
"node_modules/@vueup/vue-quill": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@vueup/vue-quill/-/vue-quill-1.2.0.tgz",
"integrity": "sha512-kd5QPSHMDpycklojPXno2Kw2JSiKMYduKYQckTm1RJoVDA557MnyUXgcuuDpry4HY/Rny9nGNcK+m3AHk94wag==",
"license": "MIT",
"dependencies": {
"quill": "^1.3.7",
"quill-delta": "^4.2.2"
},
"peerDependencies": {
"vue": "^3.2.41"
}
},
"node_modules/@vueuse/core": {
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.3.0.tgz",
@ -6473,6 +6487,53 @@
"node": ">=8"
}
},
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -7386,6 +7447,26 @@
"node": ">=6"
}
},
"node_modules/deep-equal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
"integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
"license": "MIT",
"dependencies": {
"is-arguments": "^1.1.1",
"is-date-object": "^1.0.5",
"is-regex": "^1.1.4",
"object-is": "^1.1.5",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.5.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -7459,6 +7540,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-lazy-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@ -7468,6 +7566,23 @@
"node": ">=8"
}
},
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/defu": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
@ -7684,6 +7799,20 @@
"underscore": "^1.13.1"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@ -7963,12 +8092,42 @@
"integrity": "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==",
"license": "MIT"
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-module-lexer": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
"integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
"license": "MIT"
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/esbuild": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
@ -8325,6 +8484,12 @@
"node": ">=6"
}
},
"node_modules/eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==",
"license": "MIT"
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@ -8383,6 +8548,12 @@
"integrity": "sha512-FjmpluvZS2PTYyhkoMfQoyEJMfe2bfAyNpa5Apa6C9n7SWUWyJkG/VFnzERuj3q9Jjo3iwBjwVsDQ7Z7sczthA==",
"license": "MIT"
},
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"license": "MIT"
},
"node_modules/external-editor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
@ -8425,6 +8596,12 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-diff": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"license": "Apache-2.0"
},
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
@ -8842,6 +9019,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/fuse.js": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz",
@ -8890,12 +9076,49 @@
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
"get-proto": "^1.0.0",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-port-please": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.1.2.tgz",
"integrity": "sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==",
"license": "MIT"
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@ -9077,6 +9300,18 @@
"node": ">= 4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@ -9140,6 +9375,45 @@
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
@ -9522,6 +9796,22 @@
"url": "https://github.com/sponsors/brc-dd"
}
},
"node_modules/is-arguments": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
"integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@ -9549,6 +9839,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-docker": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
@ -9680,6 +9986,24 @@
"@types/estree": "*"
}
},
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-ssh": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz",
@ -10525,6 +10849,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
"license": "MIT"
},
"node_modules/lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
@ -10714,6 +11044,15 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"license": "BSD-3-Clause"
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
@ -14337,6 +14676,31 @@
"node": ">=0.10.0"
}
},
"node_modules/object-is": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ofetch": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.4.1.tgz",
@ -14602,6 +14966,12 @@
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/parchment": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==",
"license": "BSD-3-Clause"
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -15851,6 +16221,60 @@
"integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
"license": "MIT"
},
"node_modules/quill": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
"license": "BSD-3-Clause",
"dependencies": {
"clone": "^2.1.1",
"deep-equal": "^1.0.1",
"eventemitter3": "^2.0.3",
"extend": "^3.0.2",
"parchment": "^1.1.4",
"quill-delta": "^3.6.2"
}
},
"node_modules/quill-delta": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-4.2.2.tgz",
"integrity": "sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==",
"license": "MIT",
"dependencies": {
"fast-diff": "1.2.0",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0"
}
},
"node_modules/quill/node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"license": "MIT",
"engines": {
"node": ">=0.8"
}
},
"node_modules/quill/node_modules/fast-diff": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
"license": "Apache-2.0"
},
"node_modules/quill/node_modules/quill-delta": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
"license": "MIT",
"dependencies": {
"deep-equal": "^1.0.1",
"extend": "^3.0.2",
"fast-diff": "1.1.2"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/radix-vue": {
"version": "1.9.13",
"resolved": "https://registry.npmjs.org/radix-vue/-/radix-vue-1.9.13.tgz",
@ -16130,6 +16554,26 @@
"regexp-tree": "bin/regexp-tree"
}
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
"integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-errors": "^1.3.0",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/reka-ui": {
"version": "1.0.0-alpha.8",
"resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-1.0.0-alpha.8.tgz",
@ -17052,6 +17496,38 @@
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC"
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/set-function-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",

View File

@ -21,6 +21,7 @@
"@popperjs/core": "^2.11.8",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"@vueup/vue-quill": "^1.2.0",
"axios": "^1.7.7",
"bootstrap": "^5.3.3",
"docx": "^9.1.1",

View File

@ -1,4 +1,5 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="container-fluid">
<div class="row">
<div class="col-12">
@ -143,29 +144,35 @@
:hasFooter="false"
@close="closeModal"
>
<admin-notification-form
<AdminNotificationForm
ref="tabFormBuilder"
:formData="notificationItem"
@close-modal="closeModal"
></admin-notification-form>
></AdminNotificationForm>
</base-modal>
</div>
</NuxtLayout>
</template>
<script>
import notificationMixin from "~/mixins/notifications/notificationMixin";
import adminMenu from "~/json/admin/json/menu.json";
import { defineAsyncComponent } from "vue";
export default {
name: "adminNotifications",
setup() {
definePageMeta({
name: "adminNotifications",
layout: false,
});
},
extends: notificationMixin,
mounted() {
// this.canView = true;
this.checkPermisionBeforGetList("notification_edit").then(() => {
this.checkPermisionBeforGetList("notification_edit" ).then(() => {
this.getList();
this.numberOfMark();
});
@ -182,6 +189,7 @@ export default {
data() {
return {
showModal: false,
adminMenu: adminMenu,
};
},
@ -191,7 +199,7 @@ export default {
this.openModal();
},
onDeleteItem(item) {
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
@ -208,13 +216,13 @@ export default {
openModal() {
this.showModal = true;
setTimeout(() => {
$("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
}, 500);
// setTimeout(() => {
// $("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
// }, 500);
},
closeModal(isCreate = false) {
$("#base-modal").modal("hide");
// $("#base-modal").modal("hide");
this.showModal = false;
if (isCreate)
setTimeout(() => {
this.showModal = false;
@ -229,7 +237,12 @@ export default {
}, 500);
},
},
components: {
AdminNotificationForm: defineAsyncComponent(() =>
import("@/components/admin/modal/AdminNotificationForm.vue")
),
},
};
</script>

View File

@ -0,0 +1,131 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="m-2">
<the-content-loading v-if="fetchingData"></the-content-loading>
<!-- <my-quill
:parentButtonLoading="buttonLoading"
v-else
:tinyText="tinyText"
@input="onSave"
@on-save="onSave"
></my-quill> -->
<quill-editor
v-else
v-model="tinyText"
content-type="html"
:options="editorOptions"
></quill-editor>
<button @click="onSave" type="button" class="btn btn-primary mt-3">
ذخیره
</button>
</div>
</NuxtLayout>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
import adminMenu from "~/json/admin/json/menu.json";
export default {
name: "dataSettingContactUs",
setup() {
definePageMeta({
name: "dataSettingContactUs",
layout: false,
});
},
created() {
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
data() {
return {
adminMenu: adminMenu,
httpService: {},
buttonLoading: false,
tinyText: "",
fetchingData: false,
data: undefined,
editorOptions: {
theme: "snow", // تم ویرایشگر: 'snow' یا 'bubble'
placeholder: "متن خود را بنویسید...",
modules: {
toolbar: [
[{ header: [1, 2, 3, false] }], // سطح هدینگها
["bold", "italic", "underline", "strike"], // دکمههای استایل متن
[{ color: [] }, { background: [] }], // رنگ متن و پسزمینه
[{ list: "ordered" }, { list: "bullet" }], // لیستهای شمارهدار و نقطهای
["blockquote", "code-block"], // نقلقول و کد
[{ align: [] }], // تراز بندی متن
["link", "image", "video"], // افزودن لینک، تصویر، و ویدیو
["clean"], // حذف فرمتها
],
},
},
};
},
methods: {
getData() {
var vm = this;
this.fetchingData = true;
var url = settingsApi.app.getByKey;
url = url.replace("{{key_option}}", "conect_text");
// let url = apis.admin.get.replace('{{system}}', this.$route.meta.apiKey)
this.httpService
.getRequest(url)
.then((response) => {
vm.fetchingData = false;
this.tinyText = response.data.hits.hits[0]._source.value;
this.data = response.data.hits.hits[0]._source;
})
.catch((error) => {})
.finally(() => {
vm.fetchingData = false;
});
},
onSave(newContent) {
if (this.buttonLoading) return;
this.buttonLoading = true;
// var url = apis.admin.save;
// const payload = { ...this.data, ...{ value: newContent } }
var url = settingsApi.app.saveByKey;
url = url.replace("{{key_option}}", "conect_text");
const payload = { value: newContent };
this.httpService
.postRequest(url, payload)
.then((response) => {
mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
});
})
.catch((error) => {})
.finally(() => {
this.buttonLoading = false;
});
},
},
};
</script>

143
pages/admin/about/index.vue Normal file
View File

@ -0,0 +1,143 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="m-2">
<the-content-loading v-if="fetchingData"></the-content-loading>
<!--
<my-quillr
:parentButtonLoading="buttonLoading"
v-else
:tinyText="tinyText"
@input="onSave"
@on-save="onSave"
></my-quillr> -->
<quill-editor
v-else
:content="tinyText"
ref="quillEditor"
content-type="html"
theme="snow"
@input="onInputChange"
:options="editorOptions"
></quill-editor>
<button @click="onSave" type="button" class="btn btn-primary mt-3">
ذخیره
</button>
</div>
</NuxtLayout>
</template>
<script>
import { render } from "vue";
import settingsApi from "~/apis/settingsApi";
import adminMenu from "~/json/admin/json/menu.json";
export default {
name: "dataSettingAboutUs",
setup() {
definePageMeta({
name: "dataSettingAboutUs",
layout: false,
});
},
created() {
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
data() {
return {
adminMenu: adminMenu,
httpService: {},
buttonLoading: false,
tinyText: "",
render: 0,
fetchingData: false,
data: undefined,
editorOptions: {
theme: "snow", // تم ویرایشگر: 'snow' یا 'bubble'
placeholder: "متن خود را بنویسید...",
modules: {
toolbar: [
[{ header: [1, 2, 3, false] }], // سطح هدینگها
["bold", "italic", "underline", "strike"], // دکمههای استایل متن
[{ color: [] }, { background: [] }], // رنگ متن و پسزمینه
[{ list: "ordered" }, { list: "bullet" }], // لیستهای شمارهدار و نقطهای
["blockquote", "code-block"], // نقلقول و کد
[{ align: [] }, { direction: "rtl" }], // تراز بندی متن
["link", "image", "video"], // افزودن لینک، تصویر، و ویدیو
["clean"], // حذف فرمتها
],
},
},
};
},
methods: {
getData() {
var vm = this;
this.fetchingData = true;
var url = settingsApi.app.getByKey;
url = url.replace("{{key_option}}", "about_text");
// let url = apis.admin.get.replace('{{system}}', this.$route.meta.apiKey)
this.httpService
.getRequest(repoUrl() + url)
.then((response) => {
console.log("🚀 ~ .then ~ response:", response);
vm.fetchingData = false;
this.tinyText = response.hits.hits[0]._source.value;
this.data = response.hits.hits[0]._source;
})
.catch((error) => {})
.finally(() => {
vm.fetchingData = false;
});
},
onInputChange(event) {
// console.log("🚀 ~ onInputChange ~ event:", event);
// this.tinyText = event
},
onSave(newContent) {
if (this.buttonLoading) return;
this.buttonLoading = true;
// var url = apis.admin.save;
// const payload = { ...this.data, ...{ value: newContent } }
var url = settingsApi.app.saveByKey;
url = url.replace("{{key_option}}", "about_text");
const payload = { value: newContent };
this.httpService
.postRequest(url, payload)
.then((response) => {
mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
});
})
.catch((error) => {})
.finally(() => {
this.buttonLoading = false;
});
},
},
};
</script>

View File

@ -1,4 +1,5 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div>
<the-content-loading v-if="fetchingData"></the-content-loading>
@ -24,20 +25,40 @@
</div>
</div>
</NuxtLayout>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
import adminMenu from "~/json/admin/json/menu.json";
export default {
name: "searchAmplify",
setup() {
definePageMeta({
name: "searchAmplify",
layout: false,
});
},
created() {
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
data() {
return {
adminMenu: adminMenu,
httpService: {},
stopWords: '',
fetchingData: false,
buttonLoading: false,
@ -57,7 +78,7 @@ export default {
url = url.replace("{{key_option}}", "search_amplify");
// let url = apis.admin.get.replace('{{system}}', this.$route.meta.apiKey)
ApiService.getRequest(url)
this.httpService.getRequest(url)
.then((response) => {
this.payload = response.data.hits.hits[0]._source;
this.properties = JSON.parse(response.data.hits.hits[0]._source.value);
@ -79,9 +100,9 @@ export default {
const payload = { value: JSON.stringify(this.properties) }
ApiService.postRequest(url, payload)
this.httpService.postRequest(url, payload)
.then((response) => {
this.mySwalToast({
mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
@ -93,17 +114,6 @@ export default {
})
}
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
};
</script>

View File

@ -1,5 +1,6 @@
<template>
<div>
<NuxtLayout name="default" :menu="adminMenu">
<div class="m-3">
<the-content-loading v-if="fetchingData"></the-content-loading>
<form v-else @submit.prevent="onSave()">
@ -17,23 +18,41 @@
<button-component
type="submit"
classes="btn-primary"
class="mt-2"
:buttonText="saveButtonText"
>
</button-component>
</form>
</div>
</NuxtLayout>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
import adminMenu from "~/json/admin/json/menu.json";
export default {
name: "stopWord",
setup() {
definePageMeta({
name: "stopWord",
layout: false,
});
},
created() {
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
props: {
saveButtonText: {
default: "ذخیره",
@ -41,6 +60,8 @@ export default {
},
data() {
return {
adminMenu: adminMenu,
httpService: {},
stopWords: "",
fetchingData: false,
data: undefined,
@ -57,7 +78,7 @@ export default {
url = url.replace("{{key_option}}", "words_stop");
// let url = apis.admin.get.replace("{{system}}", this.$route.meta.apiKey);
ApiService.getRequest(url)
this.httpService.getRequest(url)
.then((response) => {
vm.fetchingData = false;
@ -80,9 +101,9 @@ export default {
url = url.replace("{{key_option}}", "words_stop");
const payload = { value: this.stopWords };
ApiService.postRequest(url, payload)
this.httpService.postRequest(url, payload)
.then((response) => {
this.mySwalToast({
mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
@ -94,17 +115,6 @@ export default {
});
},
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
};
</script>

View File

@ -1,74 +1,84 @@
<template>
<div class="pages">
<sub-header
myClass="mt-0 mb-3"
:hasViewMode="false"
:showDetailsPanel="false"
title="فهرست فرم‌ها"
@show-details="newForm"
></sub-header>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages">
<sub-header
myClass="mt-0 mb-3"
:hasViewMode="false"
:showDetailsPanel="false"
title="فهرست فرم‌ها"
@show-details="newForm"
></sub-header>
<div class="pages-content ps-1">
<template v-if="canView">
<my-table
height="calc(100vh - 15em)"
:isDraggable="false"
:items="items"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:tableActions="tableActions"
:paginationInfo="pagination"
:sortingInfo="sorting"
@delete-table-item="deleteItem"
@edit-table-item="editItem"
@select-list-columns="selectListColumnsEdit"
@show-details="showDetails"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
@on-linked-title-click="onLinkedTitleClick"
/>
</template>
<no-data v-else>
<the-content-loading v-if="fetchingData"></the-content-loading>
<div class="pages-content ps-1">
<template v-if="canView">
<my-table
height="calc(100vh - 15em)"
:isDraggable="false"
:items="items"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:tableActions="tableActions"
:paginationInfo="pagination"
:sortingInfo="sorting"
@delete-table-item="deleteItem"
@edit-table-item="editItem"
@select-list-columns="selectListColumnsEdit"
@show-details="showDetails"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
@on-linked-title-click="onLinkedTitleClick"
/>
</template>
<no-data v-else>
<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 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>
</div>
</div>
</no-data>
</no-data>
<form-show
v-if="shwoPreviewForm"
:selectedItem="rowItem"
:tableColumns="tableColumns"
@edit-item="formShowEditItem"
@close-form-show="closeFormShow"
></form-show>
<FormShow
v-if="shwoPreviewForm"
:selectedItem="rowItem"
:tableColumns="tableColumns"
@edit-item="formShowEditItem"
@close-form-show="closeFormShow"
></FormShow>
</div>
</div>
</div>
</NuxtLayout>
</template>
<script>
import keyValueApi from "@apis/keyValueApi";
import HttpService from "@services/httpService";
import tableActions from "@forms/json/formListTableAction";
import { mapGetters, mapMutations, mapActions } from "vuex";
import keyValueApi from "~/apis/keyValueApi";
import adminMenu from "~/json/admin/json/menu.json";
// import HttpService from "@services/httpService";
import tableActions from "~/json/admin/json/formListTableAction";
// import { mapGetters, mapMutations, mapActions } from "vuex";
import { mapState, mapActions } from "pinia";
import { defineAsyncComponent } from "vue";
import { useCommonStore } from "~/stores/commonStore";
import { usePermitStore } from "~/stores/permitStore";
export default {
name: "formList",
setup() {
definePageMeta({
name: "formList",
layout: false,
});
},
beforeMount() {
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.httpService = new HttpService();
this.checkPermisionBeforGetList();
},
watch: {
@ -79,6 +89,7 @@ export default {
},
data() {
return {
adminMenu: adminMenu,
canView: true,
rowItem: {},
shwoPreviewForm: false,
@ -107,11 +118,13 @@ export default {
};
},
computed: {
...mapGetters(["getPanelStatus"]),
...mapState(useCommonStore, ["getPanelStatus"]),
},
methods: {
...mapMutations(["TOGGLE_PANEL"]),
...mapActions(["checkPermissions"]),
// ...mapMutations(["TOGGLE_PANEL"]),
...mapActions(useCommonStore, ["TOGGLE_PANEL"]),
...mapActions(useCommonStore, ["checkPermissions"]),
// ...mapActions(["checkPermissions"]),
checkPermisionBeforGetList() {
this.checkPermissions({ permission: "forms_list", _this: this })
.then(() => {
@ -166,7 +179,7 @@ export default {
...this.sorting,
...this.pagination,
};
let url = this.keyValueMicroServiceName + keyValueApi.forms.list;
let url = keyValueUrl() + keyValueApi.forms.list;
return await this.httpService
.postRequest(url, formData)
.then((response) => {
@ -214,7 +227,7 @@ export default {
id: this.items[index].id,
};
let url = this.keyValueMicroServiceName + keyValueApi.forms.delete;
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
@ -274,8 +287,10 @@ export default {
},
},
components: {
FormShow: () =>
import( "@forms/forms/FormShow.vue"),
// FormShow: () => import("@forms/forms/FormShow.vue"),
FormShow: defineAsyncComponent(() =>
import("@/components/admin/components/FormShow.vue")
),
},
};
</script>

View File

@ -1,138 +1,149 @@
<template>
<div class="container-fluid">
<div class="row justify-content-center">
<template v-if="canView">
<!--start: show content if user entered the from title or is edit mode -->
<div v-if="isFormTitleEntered" class="col">
<h5 class="mb-4">
{{ keyValue?.value ?? "عنوان فرم وارد نشده است." }}
<NuxtLayout name="default" :menu="adminMenu">
<div class="container-fluid">
<div class="row justify-content-center">
<template v-if="canView">
<!--start: show content if user entered the from title or is edit mode -->
<div v-if="isFormTitleEntered" class="col">
<h5 class="mb-4">
{{ keyValue?.value ?? "عنوان فرم وارد نشده است." }}
<button-component
classes="d-inline-flex"
@click="openNewFormModal"
buttonText=""
>
<span class="tavasi tavasi-Component-242--1"></span>
</button-component>
</h5>
<button-component
classes="d-inline-flex"
@click="openNewFormModal"
buttonText=""
>
<span class="tavasi tavasi-Component-242--1"></span>
</button-component>
</h5>
<div class="row no-gutters justify-content-center">
<div class="col">
<div class="list-and-actions-container">
<!-- load Simple/Tab component -->
<keep-alive>
<component
:ref="formMode"
:is="formMode"
:formTitleData="form"
:newFormItem="newFormItem"
@open-new-form-item="openNewFormItem"
></component>
</keep-alive>
<div class="row no-gutters justify-content-center">
<div class="col">
<div class="list-and-actions-container">
<!-- load Simple/Tab component -->
<keep-alive>
<component
:ref="formMode"
:is="formMode"
:formTitleData="form"
:newFormItem="newFormItem"
@open-new-form-item="openNewFormItem"
></component>
</keep-alive>
<!--start: form actions ( save/preview form) -->
<div class="d-flex justify-content-end mt-5 ms-3 form-actions">
<button-component
classes="btn btn-secondary mx-2"
@click="showFormPreView"
buttonText="پیش نمایش فرم"
<!--start: form actions ( save/preview form) -->
<div
class="d-flex justify-content-end mt-5 ms-3 form-actions"
>
</button-component>
<button-component
classes="btn btn-secondary mx-2"
@click="showFormPreView"
buttonText="پیش نمایش فرم"
>
</button-component>
<button-component
classes="btn btn-primary"
@click="saveFinalForm"
buttonText="ذخیره"
>
</button-component>
<button-component
classes="btn btn-primary"
@click="saveFinalForm"
buttonText="ذخیره"
>
</button-component>
</div>
<!--end: form actions ( save/preview form) -->
</div>
<!--end: form actions ( save/preview form) -->
</div>
<!-- start: create new form element -->
<div class="col-auto" v-if="showNewFormItem">
<NewFormItem
:key="changeDetectionCounter"
@close-new-form-item="closeNewFormItem"
@add-item-content="addFormItemToFormElements"
:editFormData="editFormData"
></NewFormItem>
</div>
<!-- end: create new form element -->
</div>
<!-- start: create new form element -->
<div class="col-auto" v-if="showNewFormItem">
<new-form-item
:key="changeDetectionCounter"
@close-new-form-item="closeNewFormItem"
@add-item-content="addFormItemToFormElements"
:editFormData="editFormData"
></new-form-item>
</div>
<!-- end: create new form element -->
</div>
</div>
<!--end: show content if user entered the from title or is edit mode -->
</template>
<no-data v-else>
<the-content-loading v-if="fetchingData"></the-content-loading>
<!--end: show content if user entered the from title or is edit mode -->
</template>
<no-data v-else>
<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 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>
</div>
</div>
</no-data>
</no-data>
</div>
<!-- create new form modal -->
<base-modal
v-if="showNewFormTitleModal"
modalSize="modal-md"
modalTitle="فرم جدید"
@close="closeFormModal"
@save="saveFormTitle"
>
<form-builder
ref="titleFormBuilder"
:formElements="formItem"
:formData="form"
></form-builder>
</base-modal>
<!--form preview modal -->
<base-modal
v-if="showPreviewModal"
:showSaveButton="false"
modalSize="modal-lg"
modalTitle="فرم پیش نمایش"
@close="closePreviewModal"
@save="saveFinalForm"
>
<!-- displayMode : horizontal | vertical -->
<form-builder
ref="previewFormBuilder"
displayMode="horizontal"
:formElements="previewFormItems"
:formData="previewFormItemsData"
></form-builder>
</base-modal>
</div>
<!-- create new form modal -->
<base-modal
v-if="showNewFormTitleModal"
modalSize="modal-md"
modalTitle="فرم جدید"
@close="closeFormModal"
@save="saveFormTitle"
>
<form-builder
ref="titleFormBuilder"
:formElements="formItem"
:formData="form"
></form-builder>
</base-modal>
<!--form preview modal -->
<base-modal
v-if="showPreviewModal"
:showSaveButton="false"
modalSize="modal-lg"
modalTitle="فرم پیش نمایش"
@close="closePreviewModal"
@save="saveFinalForm"
>
<!-- displayMode : horizontal | vertical -->
<form-builder
ref="previewFormBuilder"
displayMode="horizontal"
:formElements="previewFormItems"
:formData="previewFormItemsData"
></form-builder>
</base-modal>
</div>
</NuxtLayout>
</template>
<script>
import keyValueApi from "@apis/keyValueApi";
import HttpService from "@services/httpService";
import { mapActions } from "vuex";
import keyValueApi from "~/apis/keyValueApi";
import adminMenu from "~/json/admin/json/menu.json";
// import HttpService from "@services/httpService";
// import { mapActions } from "vuex";
import { mapState, mapActions } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
import { defineAsyncComponent } from "vue";
export default {
name: "newForm",
setup() {
definePageMeta({
name: "newForm",
layout: false,
});
},
beforeMount() {
this.httpService = new HttpService();
// this.httpService = new HttpService();
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.checkPermisionBeforGetList();
},
data() {
return {
adminMenu: adminMenu,
canView: false,
changeDetectionCounter: 0,
isFormTitleEntered: false,
@ -221,7 +232,8 @@ export default {
};
},
methods: {
...mapActions(["checkPermissions"]),
// ...mapActions(["checkPermissions"]),
...mapActions(useCommonStore, ["checkPermissions"]),
checkPermisionBeforGetList() {
const isEditMode = Boolean(this.$route.params.id);
this.checkPermissions({
@ -260,7 +272,7 @@ export default {
this.buttonLoading = true;
const url =
this.keyValueMicroServiceName + this.$route.params.id
this.keyValueUrl() + this.$route.params.id
? keyValueApi.forms.edit
: keyValueApi.forms.add;
@ -279,7 +291,7 @@ export default {
this.httpService
.postRequest(url, formData)
.then((res) => {
this.mySwalToast({
mySwalToast({
title: res.message,
html: null,
icon: "success",
@ -331,7 +343,7 @@ export default {
if (this.fetchingData) return;
this.fetchingData = true;
const url = this.keyValueMicroServiceName + keyValueApi.forms.get;
const url = this.keyValueUrl()+ keyValueApi.forms.get;
return await this.httpService
.getRequest(url + "/" + formId)
.then((res) => {
@ -358,7 +370,7 @@ export default {
this.form = this.$refs.titleFormBuilder.localFormData;
const url =
this.keyValueMicroServiceName + this.$route.params.id
this.keyValueUrl() + this.$route.params.id
? keyValueApi.forms.edit
: keyValueApi.forms.add;
@ -373,7 +385,7 @@ export default {
this.httpService
.postRequest(url, formData)
.then((res) => {
this.mySwalToast({
mySwalToast({
title: "تبریک",
html: res.message,
icon: "success",
@ -415,17 +427,18 @@ export default {
},
},
components: {
NewFormItem: () =>
import(
"@forms/forms/NewFormItem.vue"
),
SimpleForm: () =>
import(
"@forms/components/SimpleForm.vue"
),
TabForm: () =>
import( "@forms/components/TabForm.vue"),
// NewFormItem: () => import("@forms/forms/NewFormItem.vue"),
// SimpleForm: () => import("@forms/components/SimpleForm.vue"),
// TabForm: () => import("@forms/components/TabForm.vue"),
TabForm: defineAsyncComponent(() =>
import("@/components/admin/components/TabForm.vue")
),
SimpleForm: defineAsyncComponent(() =>
import("@/components/admin/components/SimpleForm.vue")
),
NewFormItem: defineAsyncComponent(() =>
import("@/components/admin/components/NewFormItem.vue")
),
},
};
</script>

View File

@ -1,106 +1,107 @@
<template>
<div class="container-fluid">
<div class="row justify-content-center">
<template v-if="canView">
<div class="col-12">
<div class="sub-header mb-3">
<div class="d-flex">
<NuxtLayout name="default" :menu="adminMenu">
<div class="container-fluid">
<div class="row justify-content-center">
<template v-if="canView">
<div class="col-12">
<div class="sub-header mb-3">
<div class="d-flex">
<label class="ms-2" for="form_id">فرم: </label>
<select
name="form_id"
id="form_id"
v-model="formId"
class="form-control text__14"
@change="showFormItem"
<div class="d-flex">
<label class="ms-2" for="form_id">فرم: </label>
<select
name="form_id"
id="form_id"
v-model="formId"
class="form-control text__14"
@change="showFormItem"
>
<template v-if="forms.length">
<option disabled :value="undefined" selected>
انتخاب مورد
</option>
<option
v-for="(form, index) in forms"
:key="index"
:value="form.id"
>
{{ form.title }}
</option>
</template>
<option v-else :value="undefined" selected>
موردی ثبت نشده است.
</option>
</select>
</div>
<div class="select-diplay-mode">
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="displayMode"
id="table"
:value="0"
v-model="selectedForm.listType"
/>
<label class="form-check-label" for="table">جدولی</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="displayMode"
id="list"
:value="1"
v-model="selectedForm.listType"
/>
<label class="form-check-label" for="list">فهرستی</label>
</div>
</div>
</div>
<div class="subset-sub-header">
<button-component
title="ایجاد"
classes="btn d-inline-flex px-2 "
@click="openForm"
buttonText=""
>
<template v-if="forms.length">
<option disabled :value="undefined" selected>
انتخاب مورد
</option>
<option
v-for="(form, index) in forms"
:key="index"
:value="form.id"
>
{{ form.title }}
</option>
</template>
<option v-else :value="undefined" selected>
موردی ثبت نشده است.
</option>
</select>
<span class="tavasi tavasi-Component-212--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
<div class="select-diplay-mode">
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="displayMode"
id="table"
:value="0"
v-model="selectedForm.listType"
/>
<label class="form-check-label" for="table">جدولی</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="displayMode"
id="list"
:value="1"
v-model="selectedForm.listType"
/>
<label class="form-check-label" for="list">فهرستی</label>
</div>
</div>
</div>
<div class="subset-sub-header">
<button-component
title="ایجاد"
classes="btn d-inline-flex px-2 "
@click="openForm"
buttonText=""
>
<span class="tavasi tavasi-Component-212--1"
><span class="path1"></span><span class="path2"></span
><span class="path3"></span
></span>
</button-component>
</div>
</div>
</div>
<div class="col">
<div class="list-and-actions-container">
<my-table
:key="changeDetectionCounter"
height="auto"
maxHeight="calc(100vh - 15em)"
:isDraggable="true"
:isSortable="true"
:items="
selectedForm[LIST_TYPES[selectedForm.listType]]?.items ?? []
"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:tableActions="tableActions"
:paginationInfo="pagination"
@edit-table-item="editItem"
@delete-table-item="deleteItem"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<div class="col">
<div class="list-and-actions-container">
<my-table
:key="changeDetectionCounter"
height="auto"
maxHeight="calc(100vh - 15em)"
:isDraggable="true"
:isSortable="true"
:items="
selectedForm[LIST_TYPES[selectedForm.listType]]?.items ?? []
"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:tableActions="tableActions"
:paginationInfo="pagination"
@edit-table-item="editItem"
@delete-table-item="deleteItem"
@onSort="onSort"
@on-linked-title-click="onLinkedTitleClick"
/>
<div
class="d-flex justify-content-end mt-5 ms-3 form-actions"
v-if="showSaveButton"
>
<!-- <button
<div
class="d-flex justify-content-end mt-5 ms-3 form-actions"
v-if="showSaveButton"
>
<!-- <button
@click.prevent="resetForm()"
type="button"
class="btn btn-secondary mx-2"
@ -108,49 +109,54 @@
>
باز نشانی
</button> -->
<button
@click.prevent="saveFinalForm()"
type="button"
class="btn btn-primary"
>
ذخیره
</button>
<button
@click.prevent="saveFinalForm()"
type="button"
class="btn btn-primary"
>
ذخیره
</button>
</div>
</div>
</div>
</div>
<!-- new form item to create new element -->
<div class="col-auto" v-if="shwoPreviewForm">
<table-column-select-form
:selectedItem="rowItem"
:selectedForm="selectedForm"
@close-form-show="closeFormShow"
@update-column="updateColumn"
></table-column-select-form>
</div>
</template>
<no-data v-else>
<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>
عدم دسترسی
<!-- new form item to create new element -->
<div class="col-auto" v-if="shwoPreviewForm">
<table-column-select-form
:selectedItem="rowItem"
:selectedForm="selectedForm"
@close-form-show="closeFormShow"
@update-column="updateColumn"
></table-column-select-form>
</div>
</div>
</no-data>
</template>
<no-data v-else>
<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>
</div>
</no-data>
</div>
</div>
</div>
</NuxtLayout>
</template>
<script>
import apis from "@apis/adminApi";
import HttpService from "@services/httpService";
// import tableActions from "@forms/json/selectListColumnAction";
import apis from "~/apis/adminApi";
import adminMenu from "~/json/admin/json/menu.json";
import { mapState, mapActions } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
import { defineAsyncComponent } from "vue";
// import HttpService from "@services/httpService";
import tableActions from "~/json/admin/json/selectListColumnAction.json";
// import { mapActions } from "vuex";
const LIST_TYPES = {
@ -163,16 +169,18 @@ export default {
setup() {
definePageMeta({
name: "selectListColumnsCreate",
layout: false,
});
},
mounted() {
this.httpService = new HttpService();
// this.httpService = new HttpService();
this.httpService = useNuxtApp()["$http"];
this.checkPermisionBeforGetList();
},
data() {
return {
canView: false,
adminMenu: adminMenu,
changeDetectionCounter: 0,
LIST_TYPES: LIST_TYPES,
rowItem: {},
@ -215,7 +223,8 @@ export default {
},
methods: {
...mapActions(["checkPermissions"]),
...mapActions(useCommonStore, ["checkPermissions"]),
// ...mapActions(["checkPermissions"]),
checkPermisionBeforGetList() {
this.checkPermissions({
permission: "forms_select-list-columns",
@ -282,7 +291,7 @@ export default {
this.httpService
.postRequest(url, formData)
.then((res) => {
this.mySwalToast({
mySwalToast({
title: res.message,
html: null,
icon: "success",
@ -307,7 +316,7 @@ export default {
...this.pagination,
};
let url = this.keyValueMicroServiceName + apis.projectForm.list;
let url = keyValueUrl() + apis.projectForm.list;
return await this.httpService
.postRequest(url, formData)
.then((response) => {
@ -364,7 +373,7 @@ export default {
].items.filter((item) => item.key == updatedColumn.key);
if (res.length)
this.mySwalToast({
mySwalToast({
title: "ستونی با چنین مشخصاتی قبلا ایجاد شده است.",
html: null,
icon: "error",
@ -414,7 +423,7 @@ export default {
this.selectedForm[this.LIST_TYPES[this.selectedForm.listType]].items
.length > 1
) {
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
@ -425,7 +434,7 @@ export default {
}
});
} else
this.mySwalToast({
mySwalToast({
title: "حداقل تعداد ستون های جدول یک می باشد.",
html: null,
icon: "error",
@ -439,7 +448,7 @@ export default {
components: {
TableColumnSelectForm: defineAsyncComponent(() =>
import("@components/forms/TableColumnSelectForm.vue")
)
),
},
};
</script>

View File

@ -1,77 +1,85 @@
<template>
<div>
<Multiselect
:allow-empty="false"
:searchable="true"
:close-on-select="true"
:show-labels="false"
:value="value"
:options="options"
class="multi mb-2"
@select="select"
label="label"
track-by="key"
placeholder="دسته"
:hide-selected="false"
:max-height="200"
:max-width="200"
>
</Multiselect>
<MyTable
height="auto"
maxHeight="calc(100vh - 9em)"
class="my-table"
ref="sectionsTable"
:hasSearch="false"
:tableActions="tableActions"
:items="sections"
:tableColumns="tableColumns"
:paginationInfo="pagination"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="editTableItem"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<!-- :fetchingData="fetchingData" :totalPages="pagination.pages"
<NuxtLayout name="default" :menu="adminMenu">
<div>
<Multiselect
:allow-empty="false"
:searchable="true"
:close-on-select="true"
:show-labels="false"
:value="value"
:options="options"
class="multi mb-2"
@select="select"
label="label"
track-by="key"
placeholder="دسته"
:hide-selected="false"
:max-height="200"
:max-width="200"
>
</Multiselect>
<my-table
height="auto"
maxHeight="calc(100vh - 9em)"
class="my-table"
ref="sectionsTable"
:hasSearch="false"
:tableActions="tableActions"
:items="sections"
:tableColumns="tableColumns"
:paginationInfo="pagination"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="editTableItem"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<!-- :fetchingData="fetchingData" :totalPages="pagination.pages"
@delete-table-item="deleteItem" @edit-table-item="toggleRolesPanel"
@page-changed="pageChanged" @page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged" -->
<!-- :paginationInfo="pagination"
<!-- :paginationInfo="pagination"
:sortingInfo="sorting -->
</MyTable>
<base-modal
v-if="openSubjectForm"
modalSize="modal-lg"
:hasFooter="false"
@close="closeModal"
>
<component
:is="slotComponentName"
:editList="editList"
</my-table>
<base-modal
v-if="openSubjectForm"
modalSize="modal-lg"
:hasFooter="false"
@close="closeModal"
></component>
</base-modal>
</div>
>
<component
:is="slotComponentName"
:editList="editList"
@close="closeModal"
></component>
</base-modal>
</div>
</NuxtLayout>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
import adminMenu from "~/json/admin/json/menu.json";
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",
setup() {
definePageMeta({
name: "guidesList",
layout: false,
});
},
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(["organNameGetter"]),
...mapState(useCommonStore, ["organNameGetter"]),
// ...mapState(["organNameGetter"]),
myActiveSchema() {
return this.helpSchemaGetter?.find((item) => {
return item.key == "help";
@ -79,7 +87,7 @@ export default {
},
},
mounted() {
let localStoageHelpSchema = useStorage("settingSchema",undefined).value;
let localStoageHelpSchema = useStorage("settingSchema", undefined).value;
if (localStoageHelpSchema) {
let helpSchema = JSON.parse(localStoageHelpSchema);
@ -93,6 +101,7 @@ export default {
},
data() {
return {
adminMenu: adminMenu,
options: [{ name: "جستجو" }, { name: "محتوا" }, { name: "مطالعه" }],
httpService: undefined,
value: "",
@ -160,11 +169,12 @@ export default {
};
},
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
// this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
this.httpService = useNuxtApp()["$http"];
},
methods: {
...mapActions("search", ["helpSchemaSetter"]),
// ...mapActions("search", ["helpSchemaSetter"]),
...mapActions(useSearchStore, ["helpSchemaSetter"]),
openModal(componentName, title) {
this.openSubjectForm = true;
this.slotComponentName = componentName;
@ -191,7 +201,7 @@ export default {
this.openModal("editModalItem", "فیلتر ها");
},
deleteItem(item) {
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار!!!",
html: "تمامی اطلاعات پاک خواهد. آیا مطمئن هستید؟ ",
}).then((result) => {
@ -199,8 +209,8 @@ export default {
var id = this.listSections[item]?._id;
let url = settingsApi.help.delete;
url = url.replace("{{id}}", id);
this.httpService.postRequest(url).then((response) => {
this.mySwalToast({
this.httpService.postRequest(repoUrl() + url).then((response) => {
mySwalToast({
title: "با موفقیت حذف شد",
// html: response.data.message,
icon: "success",
@ -215,7 +225,7 @@ export default {
url = url.replace("{{key_option}}", this.value?.key);
url = url.replace("{{offset}}", this.pagination?.offset);
url = url.replace("{{limit}}", this.pagination?.limit);
this.httpService.getRequest(url).then((response) => {
this.httpService.getRequest(repoUrl() + url).then((response) => {
let list = response.hits?.hits;
this.listSections = list;
if (this.sections.length >= 0) this.sections = [];
@ -239,7 +249,7 @@ export default {
},
getSchemas() {
this.httpService
.postRequest(searchApi.schema.list, {
.postRequest(repoUrl() + searchApi.schema.list, {
organ: this.organNameGetter,
system: "setting",
build_state: buildState(),

View File

@ -0,0 +1,242 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="page">
<div class="container">
<form>
<div class="form-row">
<div class="col-3">
<label for=""> انتخاب بخش:</label>
<multiselect
:allow-empty="false"
:searchable="true"
:close-on-select="true"
:show-labels="false"
:value="value"
:options="options"
class="multi"
@select="select"
label="label"
track-by="key"
placeholder="دسته"
:hide-selected="false"
:max-height="200"
>
</multiselect>
</div>
</div>
<div class="form-row">
<div class="col-6">
<label for="">عنوان سوال:</label>
<input
type="text"
class="form-control"
placeholder="عنوان سوال را کوتاه و واضح وارد نمایید"
v-model="title"
/>
</div>
<div class="col-6">
<label for="">نشانی صفحه:</label>
<input
type="text"
class="form-control"
placeholder="نشانی از همین سامانه انتخاب کنید"
v-model="link"
/>
</div>
</div>
<div class="form-row">
<div class="col">
<label for="">توضیح کوتاه:</label>
<input
type="text"
placeholder="توضیح مختصر حداکثر یک خط باشد"
v-model="description"
maxlength="500"
/>
</div>
</div>
<div class="form-row">
<div class="col">
<label for="" class="mt-2">توضیح مفصل:</label>
<quill-editor
v-model="editorData"
content-type="html"
:options="editorOptions"
></quill-editor>
<!-- <VueEditor
dir="rtl"
v-model="editorData"
:editorOptions="editorOptions"
></VueEditor> -->
</div>
</div>
</form>
<button class="btn-save" @click="saveData">ذخیره</button>
</div>
</div>
</NuxtLayout>
</template>
<script>
import searchApi from "~/apis/searchApi";
import settingsApi from "~/apis/settingsApi";
import adminMenu from "~/json/admin/json/menu.json";
// import { VueEditor } from "vue2-editor";
import { mapState, mapActions } from "pinia";
import { useStorage } from "@vueuse/core";
import { useCommonStore } from "~/stores/commonStore";
import { useSearchStore } from "~/stores/searchStore";
export default {
name: "adminGuides",
setup() {
definePageMeta({
name: "adminGuides",
layout: false,
});
},
beforeMount() {
// this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
this.httpService = useNuxtApp()["$http"];
},
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(useCommonStore, ["organNameGetter"]),
},
mounted() {
let localStoageHelpSchema = useStorage("settingSchema", undefined).value;
if (localStoageHelpSchema) {
let helpSchema = JSON.parse(localStoageHelpSchema);
this.helpSchemaSetter(helpSchema);
this.options = this.helpSchemaGetter[0].category;
} else this.getSchemas();
},
data() {
return {
adminMenu: adminMenu,
value: "",
editorData: "",
title: "",
link: "",
description: "",
fullDesc: "",
httpService: undefined,
options: [{ name: "جستجو" }, { name: "محتوا" }, { name: "مطالعه" }],
editorOptions: {
theme: "snow", // تم ویرایشگر: 'snow' یا 'bubble'
placeholder: "متن خود را بنویسید...",
modules: {
toolbar: [
[{ header: [1, 2, 3, false] }], // سطح هدینگها
["bold", "italic", "underline", "strike"], // دکمههای استایل متن
[{ color: [] }, { background: [] }], // رنگ متن و پسزمینه
[{ list: "ordered" }, { list: "bullet" }], // لیستهای شمارهدار و نقطهای
["blockquote", "code-block"], // نقلقول و کد
[{ align: [] }], // تراز بندی متن
["link", "image", "video"], // افزودن لینک، تصویر، و ویدیو
["clean"], // حذف فرمتها
],
},
},
};
},
methods: {
// ...mapActions("search", ["helpSchemaSetter"]),
...mapActions(useSearchStore, ["helpSchemaSetter"]),
// searchStore
select(e) {
this.value = e;
},
getSchemas() {
this.httpService
.postRequest(repoUrl() + searchApi.schema.list, {
organ: this.organNameGetter,
system: "setting",
build_state: buildState(),
})
.then((response) => {
this.helpSchemaSetter(response.data.setting);
this.options = this.helpSchemaGetter[0].category;
// this.options = response;
});
},
saveData() {
var origin = location.origin;
let cleaned = this.link;
if (this.link.startsWith(origin) || this.link == "") {
cleaned = this.link.replace(origin, "");
} else {
let errorMessage = "نشانی پیوند باید با " + origin + "شروع شود";
mySwalToast({
title: errorMessage,
// html: response.data.message,
icon: "error",
timer: 7000,
});
return "";
}
let payload = {
value_key: this.value.key,
value: this.editorData,
meta: {
title: this.title,
link: cleaned,
description: this.description,
},
};
this.httpService
.postRequest(repoUrl() + settingsApi.help.addItem, payload)
.then((response) => {
mySwalToast({
title: "با موفقیت ثبت شد",
// html: response.data.message,
icon: "success",
});
this.resetItem();
// this.helpSchemaSetter(response.data.setting);
// this.options = response;
});
},
resetItem() {
this.title = "";
this.link = "";
this.description = "";
this.editorData = "";
},
},
};
</script>
<style scoped lang="scss">
input {
border-radius: 0.5rem;
border: 2px solid rgb(127, 170, 170);
font-size: 14px;
height: 3em;
width: 100%;
&::placeholder {
color: #a7a098;
}
}
.multi {
// width: 200px;
border: 2px solid rgb(127, 170, 170);
border-radius: 0.5rem;
}
.btn-save {
width: 100px;
height: 2.5em;
float: left;
background-color: white;
margin-top: 0.8em;
border-radius: 0.5rem;
border: 2px solid rgb(127, 170, 170);
}
.page {
height: calc(100vh - 5em);
}
</style>

View File

@ -1,56 +0,0 @@
<template>
<div class="main" id="top">
<header>
<the-navbar></the-navbar>
</header>
<the-sidebar :menu="menu"></the-sidebar>
<main
class="pages-content-container p-3"
:class="{ 'expanded': !isSidebarCollapsed }"
>
<router-view></router-view>
</main>
</div>
</template>
<script>
import { mapState, mapActions } from "pinia";
import menu from "~/json/admin/json/menu.json";
export default {
data() {
return {
menu: menu,
};
},
computed: {
...mapState(["isSidebarCollapsed"]),
},
methods: {
...mapActions(["TOGGLE_PANEL"]),
toggleSidebarMenu() {
this.$store.commit('TOGGLE_SIDEBAR_MENU')
},
},
beforeCreate() {
ApiService.init(import.meta.env.VITE_REPO_BASE_URL);
},
mounted() {
this.TOGGLE_PANEL(false);
},
};
</script>
<style scoped lang="scss">
.navbar-2 {
// background: linear-gradient(45deg, #7ce2fb, #51d3f3);
// color: #fff;
background-color: #fbfafd;
// border-bottom: 1px solid #e9e9e9;
}
</style>

View File

@ -1,437 +0,0 @@
<template>
<div>
<!-- <header>
<the-navbar></the-navbar>
</header>
<the-sidebar :menu="menu"></the-sidebar> -->
<main class="pages-content-container">
<div class="pages-content mt-4 mt-lg-0">
<div class="p-3" :class="{ 'd-flex': showPanel }">
<div v-if="canView">
<my-table
:tableActions="tableActions"
height="calc(100vh - 17em)"
:hasSearch="true"
minHeight="25em"
maxHeight="calc(100dvh - 5em)"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="groups"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@search="searchGroups"
@reset-form="searchGroups"
@delete-table-item="deleteItem"
@edit-table-item="toggleUsersPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<slot name="tableHeaderActions">
<div class="dropdown">
<button
class="btn dropdown-toggle"
type="button"
data-toggle="dropdown"
aria-expanded="false"
>
{{ groupsTranslation[searchType] }}
</button>
<div class="dropdown-menu text-right">
<button
class="dropdown-item"
type="button"
@click.prevent="setSearchType('getGroupsWithoutAdmin')"
:class="{ active: searchType == 'getGroupsWithoutAdmin' }"
value="getGroupsWithoutAdmin"
>
{{ groupsTranslation["getGroupsWithoutAdmin"] }}
</button>
<button
class="dropdown-item"
type="button"
@click.prevent="setSearchType('getGroupsWithAdmin')"
:class="{ active: searchType == 'getGroupsWithAdmin' }"
value="getGroupsWithAdmin"
>
{{ groupsTranslation["getGroupsWithAdmin"] }}
</button>
</div>
</div>
</slot>
</my-table>
</div>
<no-data v-else>
<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 ml-1 text__32"
></span>
عدم دسترسی
</div>
</div>
</no-data>
<div class="side-panel" v-if="showPanel">
<div
class="side-panel-header d-flex mb-3 pb-3 border-bottom align-items-center"
>
<h5 class="m-0">جستجو و انتخاب مدیر گروه</h5>
<button
@click.prevent="toggleUsersPanel(undefined)"
class="btn mr-auto"
type="button"
>
<svg class="icon icon-Component-294--1">
<use xlink:href="#icon-Component-294--1"></use>
</svg>
</button>
</div>
<div class="side-panel-content">
<users-search
v-if="showPanel"
:searchResults="users"
@on-send="searchUsers"
@set-as-admin="setAsAdmin"
></users-search>
</div>
</div>
</div>
</div>
</main>
</div>
</template>
<script>
import { mapState, mapActions } from "pinia";
import menu from "~/json/admin/json/menu.json";
import adminApi from "~/apis/adminApi";
import permitApis from "~/apis/permitApi";
export default {
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
},
mounted() {
this.checkPermisionBeforGetList();
},
data() {
return {
searchType: "getGroupsWithoutAdmin",
groupsTranslation: {
getGroupsWithoutAdmin: "گروه های بدون مدیر",
getGroupsWithAdmin: "گروه های دارای مدیر",
},
groups: [],
menu: menu,
firstTimeSearching: false,
httpService: undefined,
tableActions: [
{
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",
},
{
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",
},
],
canView: false,
fetchingData: false,
tableColumns: [
{
isLink: true,
key: "title",
title: "عنوان",
width: "2",
},
{
isLink: true,
key: "desc",
title: "توضیحات",
width: "2",
},
],
pagination: {
page: 1,
pages: 0,
total: 0,
offset: 0,
limit: 10,
},
sorting: {
sortby: "title",
sortorder: "asc", // asc | desc | none
},
users: [],
loading: false,
showPanel: false,
selectedItemClone: undefined,
prevSelectedItemIndex: undefined,
};
},
methods: {
...mapState(["isSidebarCollapsed"]),
...mapActions(["checkPermissions"]),
checkPermisionBeforGetList() {
if (this.fetchingData) return;
this.fetchingData = true;
this.checkPermissions({ _this: this, permission: "groups_view" })
.then(() => {
this.getGroupsWithoutAdmin()
.then(() => {
this.canView = true;
this.fetchingData = false;
})
.catch(() => {
this.canView = false;
this.fetchingData = false;
});
})
.catch(() => {
this.canView = false;
this.fetchingData = false;
});
},
async getGroupsWithoutAdmin(query = "") {
let url = `${messageUrl()}/${adminApi.groups.groupsWithoutAdmin}`;
return await this.httpService
.getRequest(this.updateUrl(url, query))
.then((res) => {
this.groups = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
});
},
getGroupsWithAdmin() {
if (this.fetchingData) return;
this.fetchingData = true;
let url = `${messageUrl()}/${adminApi.groups.groupsWithAdmin}`;
this.httpService
.getRequest(this.updateUrl(url))
.then((response) => {
this.groups = response.data;
this.pagination = { ...this.pagination, ...response.pagination };
})
.finally(() => {
this.fetchingData = false;
});
},
updateUrl(url, query = "") {
url = url.replace("@offset", this.pagination.offset);
url = url.replace("@limit", this.pagination.limit);
url = url.replace("@sortby", this.sorting.sortby);
url = url.replace("@sortorder", this.sorting.sortorder);
// for searching groups.
if (query?.length) url = url.replace("@query", query);
else url = url.replace("/@query", query);
return url;
},
async searchUsers(query = "") {
// this.resetPagination();
let url = loginUrl() + permitApis.users.search;
url = url.replace("{{offset}}", 0);
url = url.replace("{{limit}}", 50);
url = url.replace("{{sortby}}", "username");
url = url.replace("{{sortorder}}", "desc");
// removing '/' before query if query is empty.
if (query) url = url.replace("{{query}}", query);
else url = url.replace("/{{query}}", query);
return await this.httpService.getRequest(url).then((res) => {
this.users = res.data;
// this.pagination = { ...this.pagination, ...res.pagination };
});
},
// searchUsers(query = "") {
// this.resetPagination();
// this[this.searchType](query);
// // this.getGroupsWithoutAdmin(query);
// },
searchGroups(query) {
this.resetPagination();
this[this.searchType](query);
},
setSearchType(groupType) {
this.searchType = groupType;
this.resetPagination();
this[groupType]();
},
removeGroupMember() {},
setAsAdmin(user) {
if (this.loading) return;
this.loading = true;
const url = messageUrl() + "/" + chatApi.groups.setAdmin;
let payload = {
user_id: user.id,
group_id: this.selectedItemClone.id,
};
this.httpService
.postRequest(url, payload)
.then((res) => {
this.getGroupsWithoutAdmin().then(() => {
this.loading = false;
});
this.mySwalToast({
html: res.message,
});
this.showPanel = false;
this.resetForm();
})
.finally(() => {
this.loading = false;
});
},
toggleUsersPanel(index = undefined) {
if (index !== undefined) {
if (this.prevSelectedItemIndex !== undefined)
this.groups[this.prevSelectedItemIndex].active = false;
this.prevSelectedItemIndex = index;
this.$set(this.groups[index], "active", true);
this.selectedItemClone = structuredClone(this.groups[index]);
this.showPanel = true;
} else {
this.resetForm();
}
},
resetForm() {
this.selectedItemClone = undefined;
this.users = [];
this.showPanel = false;
},
// pagination and sorting
resetPagination() {
this.pagination = {
pages: 0,
total: 0,
page: 1,
offset: 0,
limit: 10,
};
},
pageLimitChanged(paging) {
this.resetPagination();
this.pagination.limit = paging.limit;
this[this.searchType]();
},
pageChanged(paging) {
let page = paging.pageNumber;
page -= 1;
this.pagination.offset = page * paging.limit;
this.pagination.limit = paging.limit;
this.pagination.page = paging.pageNumber;
this[this.searchType]();
},
sortChanged(sorting) {
this.pagination.page = this.pagination.offset = 0;
this.sorting = sorting;
this[this.searchType]();
},
// not used yet.
deleteItem(index) {
if (this.loading) return;
this.loading = true;
let groupId = this.groups[index].id;
const payload = {
group_id: groupId,
};
const url = `${messageUrl()}/${adminApi.groups.delete}`;
this.mySwalConfirm({
title: "هشدار",
html: "با حذف گروه، تمامی مسائل و پاسخ های آن نیز حذف خواهد شد.",
icon: "warning",
}).then((result) => {
if (result.isConfirmed) {
this.httpService.postRequest(url, payload).then((res) => {
this[this.searchType]().then(() => {
this.loading = false;
// this.showPanel = false;
});
this.mySwalToast({
html: res.message,
});
});
}
});
},
openCreatePanel() {
this.selectedItemClone = undefined;
this.showPanel = true;
},
},
};
</script>
<style scoped lang="scss">
.side-panel {
padding: 1em;
width: 30em;
max-width: 100%;
background-color: #fafafa;
border-right: 1px solid #eee;
}
</style>

View File

@ -1,387 +0,0 @@
<template>
<div>
<!-- <header>
<the-navbar></the-navbar>
</header>
<the-sidebar :menu="menu"></the-sidebar> -->
<main class="pages-content-container">
<div class="pages-content mt-4 mt-lg-0">
<div class="p-3" :class="{ 'd-flex': showPanel }">
<div v-if="canView">
<my-table
:tableActions="tableActions"
height="calc(100vh - 17em)"
:hasSearch="true"
maxHeight="calc(100dvh - 5em)"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="users"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@search="searchGroups"
@reset-form="searchUsers"
@delete-table-item="deleteItem"
@edit-table-item="toggleUsersPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<template #tableHeaderActions>
<button
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class="btn btn-primary"
type="button"
>
ایجاد
</button>
</template>
</my-table>
</div>
<no-data v-else>
<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 ml-1 text__32"
></span>
عدم دسترسی
</div>
</div>
</no-data>
<div class="side-panel mx-5" v-if="showPanel">
<div class="side-panel-header d-flex mb-3 pb-3 border-bottom">
<h6 class="m-0">مدیریت کاربران</h6>
<button
@click.prevent="toggleUsersPanel(undefined)"
class="btn btn-outline-primary mr-auto"
type="button"
>
x
</button>
</div>
<div class="side-panel-content">
<new-user-form
:parentLoading="loading"
:userData="selectedItemClone"
@on-pass-by-emit="save"
></new-user-form>
</div>
</div>
</div>
</div>
</main>
</div>
</template>
<script>
import apis from "~/apis/permitApi";
import { mapState, mapActions } from "pinia";
import menu from "~/json/admin/json/menu.json";
export default {
beforeMount() {
this.httpService = new HttpService(
import.meta.env.VITE_BASE_URL + loginUrl()
);
},
mounted() {
this.checkPermisionBeforGetList();
},
// watch: {
// projectGetter() {
// this.showPanel = false;
// this.checkPermisionBeforGetList();
// },
// },
data() {
return {
menu: menu,
firstTimeSearching: false,
httpService: undefined,
tableActions: [
{
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",
},
{
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",
},
],
canView: false,
fetchingData: false,
tableColumns: [
{
isLink: true,
key: "name",
title: "نام",
width: "2",
},
{
isLink: true,
key: "lastname",
title: "نام خانوادگی",
width: "2",
},
{
key: "username",
title: "نام کاربری",
width: "2",
},
{
key: "email",
title: "ایمیل",
width: "2",
},
{
key: "is_active",
title: "فعال",
width: "2",
},
{
key: "admin",
title: "مدیر",
width: "2",
},
{
key: "mobile",
title: "موبایل",
width: "2",
},
{
key: "date_c",
title: "ایجاد",
width: "2",
},
{
key: "last-signed-int",
title: "آخرین ورود",
width: "2",
},
],
pagination: {
page: 1,
pages: 0,
total: 0,
offset: 0,
limit: 10,
},
sorting: {
sortby: "name",
sortorder: "asc", // asc | desc | none
},
users: [],
loading: false,
showPanel: false,
selectedItemClone: undefined,
prevSelectedItemIndex: undefined,
};
},
methods: {
...mapState(["isSidebarCollapsed"]),
...mapActions(["checkPermissions"]),
checkPermisionBeforGetList() {
if (this.fetchingData) return;
this.fetchingData = true;
this.checkPermissions({ _this: this, permission: "modifications_view" })
.then(() => {
this.getUsers()
.then(() => {
this.canView = true;
this.fetchingData = false;
})
.catch(() => {
this.canView = false;
this.fetchingData = false;
});
})
.catch(() => {
this.canView = false;
this.fetchingData = false;
});
},
async searchUsers(query = "") {
this.resetPagination();
let url = apis.users.search;
url = url.replace("{{offset}}", this.pagination.offset);
url = url.replace("{{limit}}", this.pagination.limit);
url = url.replace("{{sortby}}", this.sorting.sortby);
url = url.replace("{{sortorder}}", this.sorting.sortorder);
// removing '/' before query if query is empty.
if (query) url = url.replace("{{query}}", query);
else url = url.replace("/{{query}}", query);
return await this.httpService.getRequest(url).then((res) => {
this.users = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
});
},
async getUsers() {
let url = apis.users.list;
url = url.replace("{{offset}}", this.pagination.offset);
url = url.replace("{{limit}}", this.pagination.limit);
url = url.replace("{{sortby}}", this.sorting.sortby);
url = url.replace("{{sortorder}}", this.sorting.sortorder);
return await this.httpService.getRequest(url).then((res) => {
this.users = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
});
},
save(formData = undefined) {
if (this.loading) return;
this.loading = true;
const url = formData.id ? apis.users.update : apis.users.create;
formData;
this.httpService
.postRequest(url, formData)
.then((res) => {
this.getUsers().then(() => {
this.loading = false;
});
this.mySwalToast({
html: res.message,
});
this.showPanel = false;
this.resetForm();
})
.finally(() => {
this.loading = false;
});
},
deleteItem(index) {
if (this.loading) return;
this.loading = true;
let userId = this.users[index].id;
const payload = {
id: userId,
};
this.mySwalConfirm({
title: "هشدار",
html: "هشدار!!!!",
icon: "warning",
}).then((result) => {
if (result.isConfirmed) {
this.httpService
.postRequest(apis.users.delete, payload)
.then((res) => {
this.getUsers().then(() => {
this.loading = false;
this.showPanel = false;
});
this.mySwalToast({
html: res.message,
});
});
}
});
},
resetPagination() {
this.pagination = {
pages: 0,
total: 0,
page: 1,
offset: 0,
limit: 10,
};
},
pageLimitChanged(paging) {
this.resetPagination();
this.pagination.limit = paging.limit;
this.getUsers();
},
pageChanged(paging) {
let page = paging.pageNumber;
page -= 1;
this.pagination.offset = page * paging.limit;
this.pagination.limit = paging.limit;
this.pagination.page = paging.pageNumber;
this.getUsers();
},
sortChanged(sorting) {
this.pagination.page = this.pagination.offset = 0;
this.sorting = sorting;
this.getUsers();
},
openCreatePanel() {
this.selectedItemClone = undefined;
this.showPanel = true;
},
toggleUsersPanel(index = undefined) {
if (index !== undefined) {
if (this.prevSelectedItemIndex !== undefined)
this.users[this.prevSelectedItemIndex].active = false;
this.prevSelectedItemIndex = index;
this.$set(this.users[index], "active", true);
this.selectedItemClone = structuredClone(this.users[index]);
this.showPanel = true;
} else {
this.resetForm();
}
},
resetForm() {
this.selectedItemClone = undefined;
this.showPanel = false;
},
},
};
</script>
<style scoped lang="scss">
.side-panel-content {
min-width: 19em;
}
</style>

View File

@ -1,61 +0,0 @@
<template>
<div class="main" id="top">
<header>
<the-navbar></the-navbar>
</header>
<the-sidebar :menu="menu"></the-sidebar>
<main
class="pages-content-container p-3"
:class="{ 'expanded': !isSidebarCollapsed }"
>
<router-view></router-view>
</main>
</div>
</template>
<script>
import { mapState, mapActions } from "pinia";
import menu from "~/json/admin/json/menu.json";
export default {
name: "adminModuleLayout",
setup() {
definePageMeta({
name: "adminModuleLayout",
});
},
data() {
return {
menu: menu,
};
},
computed: {
...mapState(["isSidebarCollapsed"]),
},
methods: {
...mapActions(["TOGGLE_PANEL"]),
toggleSidebarMenu() {
this.$store.commit('TOGGLE_SIDEBAR_MENU')
},
},
beforeCreate() {
ApiService.init(import.meta.env.VITE_REPO_BASE_URL);
},
mounted() {
this.TOGGLE_PANEL(false);
},
};
</script>
<style scoped lang="scss">
.navbar-2 {
// background: linear-gradient(45deg, #7ce2fb, #51d3f3);
// color: #fff;
background-color: #fbfafd;
// border-bottom: 1px solid #e9e9e9;
}
</style>

View File

@ -39,84 +39,84 @@
</p>
</no-data>
<!-- <div class="side-panel" v-if="showRoles">
<div class="panel-form-header">
<h6 class="">{{ $t("DepartmentManagement") }}</h6>
</div>
<div class="side-panel" v-if="showRoles">
<div class="panel-form-header">
<h6 class="">{{ $t("DepartmentManagement") }}</h6>
</div>
<div class="side-panel-content">
<form class="form" role="section" @submit.prevent="save()">
<div class="form-group">
<label for="section_title">{{ $t("SectionTitle") }}</label>
<input
type="text"
class="form-control"
id="section_title"
name="section_title"
v-model="selectedItemClone.section_title"
/>
</div>
<div class="form-group">
<label for="action_title">{{ $t("ActionTitle") }} </label>
<input
type="text"
class="form-control"
id="action_title"
name="action_title"
v-model="selectedItemClone.action_title"
/>
</div>
<div class="form-group">
<label for="section_tag"> {{ $t("SectionTag") }}</label>
<input
type="text"
dir="ltr"
class="form-control"
id="section_tag"
name="section_tag"
v-model="selectedItemClone.section_tag"
/>
</div>
<div class="form-group">
<label for="action_tag"> {{ $t("ActionTag") }}</label>
<input
type="text"
dir="ltr"
class="form-control"
id="action_tag"
name="action_tag"
v-model="selectedItemClone.action_tag"
/>
</div>
<div class="side-panel-footer mt-4">
<div>
<button
type="submit"
class="btn btn-outline-primary"
:disabled="loading"
@click.prevent="save()"
>
<the-button-loading v-if="loading"></the-button-loading>
{{ $t("Submit") }}
</button>
<button
:disabled="loading"
@click.prevent="showRoles = false"
type="button"
class="btn btn-default"
data-dismiss="modal"
>
{{ $t("Cancel") }}
</button>
<div class="side-panel-content">
<form class="form" role="section" @submit.prevent="save()">
<div class="form-group">
<label for="section_title">{{ $t("SectionTitle") }}</label>
<input
type="text"
class="form-control"
id="section_title"
name="section_title"
v-model="selectedItemClone.section_title"
/>
</div>
</div>
</form>
<div class="form-group">
<label for="action_title">{{ $t("ActionTitle") }} </label>
<input
type="text"
class="form-control"
id="action_title"
name="action_title"
v-model="selectedItemClone.action_title"
/>
</div>
<div class="form-group">
<label for="section_tag"> {{ $t("SectionTag") }}</label>
<input
type="text"
dir="ltr"
class="form-control"
id="section_tag"
name="section_tag"
v-model="selectedItemClone.section_tag"
/>
</div>
<div class="form-group">
<label for="action_tag"> {{ $t("ActionTag") }}</label>
<input
type="text"
dir="ltr"
class="form-control"
id="action_tag"
name="action_tag"
v-model="selectedItemClone.action_tag"
/>
</div>
<div class="side-panel-footer mt-4">
<div>
<button
type="submit"
class="btn btn-outline-primary"
:disabled="loading"
@click.prevent="save()"
>
<the-button-loading v-if="loading"></the-button-loading>
{{ $t("Submit") }}
</button>
<button
:disabled="loading"
@click.prevent="showRoles = false"
type="button"
class="btn btn-default"
data-dismiss="modal"
>
{{ $t("Cancel") }}
</button>
</div>
</div>
</form>
</div>
</div>
</div> -->
</div>
</div>
</NuxtLayout>
@ -145,7 +145,6 @@ export default {
},
watch: {
projectGetter() {
this.showRoles = false;
this.checkPermisionBeforGetList();
},
getPanelStatus() {
@ -192,9 +191,7 @@ export default {
httpService: {},
canView: false,
fetchingData: false,
changeDetectionCounter: 1,
sections: [],
loading: false,
showRoles: false,
@ -212,7 +209,6 @@ export default {
sortby: "",
sortorder: "", // asc | desc
},
pagination: {
page: 1,
pages: 0,
@ -251,14 +247,11 @@ export default {
};
},
computed: {
// ...mapGetters("permit", ["projectGetter"]),
// ...mapGetters(["getPanelStatus"]),
...mapState(usePermitStore, ["projectGetter"]),
...mapState(useCommonStore, ["getPanelStatus"]),
},
methods: {
...mapActions(useCommonStore, ["checkPermissions"]),
// ...mapMutations("permit", ["SET_PROJECT"]),
...mapActions(usePermitStore, ["SET_PROJECT"]),
async getSections() {
@ -269,12 +262,12 @@ export default {
...this.sorting,
...this.pagination,
};
let url = "permit/" + apis.sections.list;
let url = permitUrl() + apis.sections.list;
return await this.httpService
.postRequest(url, payload)
.then((res) => {
this.sections = res.data.data;
this.pagination = { ...this.pagination, ...res.data.pagination };
this.sections = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
})
.finally(() => {
@ -287,18 +280,20 @@ export default {
? apis.sections.edit
: apis.sections.add;
this.httpService.postRequest(url, this.selectedItemClone).then((res) => {
this.getSections();
this.httpService
.postRequest(permitUrl() + url, this.selectedItemClone)
.then((res) => {
this.getSections();
this.mySwalToast({
title: "تبریک",
html: "اطلاعات با موفقیت ذخیره شد.",
icon: "success",
mySwalToast({
title: "تبریک",
html: "اطلاعات با موفقیت ذخیره شد.",
icon: "success",
});
this.showRoles = false;
this.resetForm();
});
this.showRoles = false;
this.resetForm();
});
},
deleteItem(index) {
@ -309,18 +304,18 @@ export default {
id: sectionId,
};
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار",
html: "از حذف این بخش مطمئن هستید؟",
icon: "warning",
}).then((result) => {
if (result.isConfirmed) {
this.httpService
.postRequest(apis.sections.delete, data)
.postRequest(permitUrl() + apis.sections.delete, data)
.then((res) => {
this.getSections();
this.mySwalToast({
mySwalToast({
title: "تبریک",
html: "بخش با موفقیت حذف گردید.",
icon: "success",
@ -374,7 +369,7 @@ export default {
this.prevSelectedItemIndex = index;
this.sections[index].active = true;
this.selectedItemClone = structuredClone(this.sections[index]);
this.selectedItemClone = this.sections[index];
} else this.resetForm();
this.showRoles = true;
@ -392,7 +387,7 @@ export default {
checkPermisionBeforGetList() {
if (this.fetchingData) return;
this.fetchingData = true;
this.checkPermissions({ permission: "sections_view", _this: this })
.then(() => {
console.info("then");
@ -432,13 +427,13 @@ export default {
},
async getProjects() {
return await this.httpService
.postRequest(apis.projects.list)
.postRequest(permitUrl() + apis.projects.list)
.then((res) => {
console.log(
"🚀 ~ returnawaitthis.httpService.postRequest ~ res:",
res
);
this.SET_PROJECT(res.data.data[0]);
this.SET_PROJECT(res.data[0]);
});
},
},
@ -447,15 +442,6 @@ export default {
// SubHeaderWithSelect: defineAsyncComponent(() =>
// import("@/components/global/SubHeaderWithSelect.vue")
// ),
// TheContentLoading: defineAsyncComponent(() =>
// import("@/components/global/TheContentLoading.vue")
// ),
// MyTable: defineAsyncComponent(() =>
// import("@/components/global/MyTable.vue")
// ),
// NoData: defineAsyncComponent(() =>
// import("@/components/global/NoData.vue")
// ),
},
};
</script>

View File

@ -1,63 +1,63 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages role-section-page p-3">
<SubHeaderWithSelect
:enableNewButton="false"
:showProjectSelect="$attrs.showProjectSelect"
@open-form="toggleRolesPanel()"
title="دسترسی های کاربران"
>
</SubHeaderWithSelect>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages role-section-page p-3">
<SubHeaderWithSelect
:enableNewButton="false"
:showProjectSelect="$attrs.showProjectSelect"
@open-form="toggleRolesPanel()"
title="دسترسی های کاربران"
>
</SubHeaderWithSelect>
<div class="pages-content">
<template v-if="canView">
<div class="container">
<div class="row">
<div class="col-12 col-md-8 mx-auto">
<ul class="nav nav-tabs mb-3">
<li
v-for="({ id, title }, index) in roles"
:key="index"
:value="id"
class="nav-item"
>
<a
class="nav-link text-center"
:class="{ active: activeTabIndex == index }"
:href="title"
@click.prevent="onTabClick(id, index)"
<div class="pages-content">
<template v-if="canView">
<div class="container">
<div class="row">
<div class="col-12 col-md-8 mx-auto">
<ul class="nav nav-tabs mb-3">
<li
v-for="({ id, title }, index) in roles"
:key="index"
:value="id"
class="nav-item"
>
{{ title }}
</a>
</li>
</ul>
<a
class="nav-link text-center"
:class="{ active: activeTabIndex == index }"
:href="title"
@click.prevent="onTabClick(id, index)"
>
{{ title }}
</a>
</li>
</ul>
<Accordion
class="role-permission"
canEdit="role-permission_edit"
:role_id="role_id"
></Accordion>
<Accordion
class="role-permission"
canEdit="role-permission_edit"
:role_id="role_id"
></Accordion>
</div>
</div>
</div>
</div>
</template>
<no-data v-else>
<the-content-loading v-if="fetchingData"></the-content-loading>
</template>
<no-data v-else>
<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 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>
</div>
</div>
</no-data>
</no-data>
</div>
</div>
</div>
</NuxtLayout>
</NuxtLayout>
</template>
<script>
@ -68,37 +68,26 @@ import { defineAsyncComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
import { usePermitStore } from "~/stores/permitStore";
// import { DEFAULT_CONFIG } from "vue-codemirror";
// import { mapGetters, mapMutations, mapActions } from "vuex";
export default {
name:"rolePermission",
name: "rolePermission",
setup() {
definePageMeta({
name: "rolePermission",
layout: false,
});
},
mounted() {
this.checkPermisionBeforGetList();
},
watch: {
projectGetter() {
this.checkPermisionBeforGetList();
},
},
components: {
// BreadCrumb: () => import("@components/BreadCrumb.vue"),
// Accordion: () => import("@permission/components/Accordion.vue"),
// SubHeaderWithSelect: defineAsyncComponent(() =>
// import("@/components/global/SubHeaderWithSelect.vue")
// ),
// TheContentLoading: defineAsyncComponent(() =>
// import("@/components/global/TheContentLoading.vue")
// ),
// TheButtonLoading: defineAsyncComponent(() =>
// import("@/components/global/TheButtonLoading.vue")
// ),
// MyTable: defineAsyncComponent(() =>
// import("@/components/global/MyTable.vue")
// ),
// NoData: defineAsyncComponent(() =>
// import("@/components/global/NoData.vue")
// ),
// BreadCrumb: defineAsyncComponent(() =>
// import("@/components/global/BreadCrumb.vue")
// ),
Accordion: defineAsyncComponent(() =>
import("@/components/admin/components/Accordion.vue")
),
@ -108,7 +97,7 @@ export default {
},
data() {
return {
adminMenu:adminMenu,
adminMenu: adminMenu,
roles: [],
httpService: {},
collapseAll: false,
@ -140,7 +129,6 @@ export default {
// ...mapMutations("permit", ["SET_PROJECT"]),
// ...mapActions("permit", ["getProjects"]),
...mapActions(useCommonStore, ["checkPermissions"]),
...mapActions(usePermitStore, ["SET_PROJECT"]),
...mapActions(usePermitStore, ["getProjects"]),
@ -150,14 +138,17 @@ export default {
this.role_id = id;
},
async getRoles() {
return await ApiService.formData(apis.roles.list, {
project_id: this.projectGetter?.id,
}).then((response) => {
this.roles = response.data.data;
return await this.httpService
.postRequest(permitUrl() + apis.roles.list, {
project_id: this.projectGetter?.id,
})
.then((response) => {
this.roles = response?.data;
this.role_id =
this.roles && this.roles[0] ? this.roles[0].id : undefined;
});
this.role_id =
this.roles && this.roles[0] ? this.roles[0].id : undefined;
});
},
checkPermisionBeforGetList() {
if (this.fetchingData) return;
@ -195,9 +186,11 @@ export default {
});
},
async getProjects() {
return await ApiService.formData(apis.projects.list).then((res) => {
this.SET_PROJECT(res.data.data[0]);
});
return await this.httpService
.postRequest(permitUrl() + apis.projects.list)
.then((res) => {
this.SET_PROJECT(res.data[0]);
});
},
setProject(id) {
// const id = +$ev.target.value;
@ -207,13 +200,5 @@ export default {
this.SET_PROJECT(project);
},
},
mounted() {
this.checkPermisionBeforGetList();
},
// watch: {
// projectGetter() {
// this.checkPermisionBeforGetList();
// },
// },
};
</script>

View File

@ -1,120 +1,119 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages role-page px-3 pb-0 pt-2">
<sub-header-with-select
canCreate="roles_new"
@open-form="toggleRolesPanel"
:showProjectSelect="$attrs.showProjectSelect"
title="نقش ها"
></sub-header-with-select>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages role-page px-3 pb-0 pt-2">
<sub-header-with-select
canCreate="roles_new"
@open-form="toggleRolesPanel"
:showProjectSelect="$attrs.showProjectSelect"
title="نقش ها"
></sub-header-with-select>
<div class="pages-content pb-0 pt-2">
<template v-if="canView">
<my-table
:tableActions="tableActions"
height="auto"
maxHeight="calc(100vh - 9em)"
class="my-table"
ref="rolesTable"
:hasSearch="false"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="roles"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="toggleRolesPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
></my-table>
</template>
<NoData v-else>
<the-content-loading v-if="fetchingData"></the-content-loading>
<div class="pages-content pb-0 pt-2">
<template v-if="canView">
<my-table
:tableActions="tableActions"
height="auto"
maxHeight="calc(100vh - 9em)"
class="my-table"
ref="rolesTable"
:hasSearch="false"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="roles"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="toggleRolesPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
></my-table>
</template>
<NoData v-else>
<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 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>
</div>
</NoData>
<div class="side-panel" v-if="showPanel">
<div class="side-panel-header">
<h6 class="">مدیریت نقش ها</h6>
</div>
</div>
</NoData>
<div class="side-panel" v-if="showPanel">
<div class="side-panel-header">
<h6 class="">مدیریت نقش ها</h6>
</div>
<div class="side-panel-content">
<form class="section-form" role="section" @submit.prevent="save()">
<div class="form-group">
<label for="title">عنوان نقش</label>
<input
type="text"
class="form-control"
id="title"
name="title"
v-model="selectedItemClone.title"
/>
</div>
<div class="side-panel-footer mt-4">
<div>
<button
type="submit"
class="btn btn-outline-primary"
:disabled="loading"
@click.prevent="save()"
>
<the-button-loading
v-if="loading"
:style="{ transform: 'scale(0.5)' }"
></the-button-loading>
ثبت
</button>
<button
:disabled="loading"
@click.prevent="showPanel = false"
type="button"
class="btn btn-default"
data-dismiss="modal"
>
لغو
</button>
<div class="side-panel-content">
<form class="section-form" role="section" @submit.prevent="save()">
<div class="form-group">
<label for="title">عنوان نقش</label>
<input
type="text"
class="form-control"
id="title"
name="title"
v-model="selectedItemClone.title"
/>
</div>
<div>
<button
v-if="selectedItemClone.id"
@click="deleteItem(selectedItemClone.id)"
title="حذف"
class="btn delete-btn btn-outline-danger"
type="button"
>
<svg class="icon icon-Component-295--1">
<use xlink:href="#icon-Component-295--1"></use>
</svg>
حذف
</button>
<div class="side-panel-footer mt-4">
<div>
<button
type="submit"
class="btn btn-outline-primary"
:disabled="loading"
@click.prevent="save()"
>
<the-button-loading
v-if="loading"
:style="{ transform: 'scale(0.5)' }"
></the-button-loading>
ثبت
</button>
<button
:disabled="loading"
@click.prevent="showPanel = false"
type="button"
class="btn btn-default"
data-dismiss="modal"
>
لغو
</button>
</div>
<div>
<button
v-if="selectedItemClone.id"
@click="deleteItemHandler(selectedItemClone.id)"
title="حذف"
class="btn delete-btn btn-outline-danger"
type="button"
>
<svg class="icon icon-Component-295--1">
<use xlink:href="#icon-Component-295--1"></use>
</svg>
حذف
</button>
</div>
</div>
</div>
</form>
</form>
</div>
</div>
</div>
</div>
</div>
</NuxtLayout>
</NuxtLayout>
</template>
<script>
// import permitApi from "@permission/permitApi";
import apis from "~/apis/permitApi";
import adminMenu from "~/json/admin/json/menu.json";
// import { mapGetters, mapMutations, mapActions } from "vuex";
import { defineAsyncComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
@ -142,7 +141,7 @@ export default {
},
data() {
return {
adminMenu:adminMenu,
adminMenu: adminMenu,
httpService: {},
tableActions: [
{
@ -228,10 +227,11 @@ export default {
...this.sorting,
...this.pagination,
};
return await ApiService.formData(permitApi.roles.list, payload)
return await this.httpService
.postRequest(permitUrl() + apis.roles.list, payload)
.then((res) => {
this.roles = res.data.data;
this.pagination = { ...this.pagination, ...res.data.pagination };
this.roles = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
})
.finally(() => {
@ -240,45 +240,55 @@ export default {
});
},
save() {
const url = this.selectedItemClone.id
? permitApi.roles.edit
: permitApi.roles.add;
const url = this.selectedItemClone.id ? apis.roles.edit : apis.roles.add;
ApiService.formData(url, this.selectedItemClone).then((res) => {
this.getRoles();
this.httpService
.postRequest(permitUrl() + url, this.selectedItemClone)
.then((res) => {
this.getRoles();
this.mySwalToast({
title: "تبریک",
html: res.data.message,
icon: "success",
mySwalToast({
title: "تبریک",
html: res.data.message,
icon: "success",
});
this.showPanel = false;
this.resetForm();
});
this.showPanel = false;
this.resetForm();
});
},
deleteItemHandler(id) {
// const foundObject = this.roles.find(obj => obj.id === id);
const index = this.roles.findIndex((obj) => obj.id === id);
this.deleteItem(index);
},
deleteItem(index) {
// debugger
let sectionId = this.roles[index].id;
const data = {
// project_id: this.projectGetter?.id,
id: sectionId,
};
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار",
html: "از حذف این بخش مطمئن هستید؟",
icon: "warning",
}).then((result) => {
if (result.isConfirmed) {
ApiService.formData(permitApi.roles.delete, data).then((res) => {
this.getRoles();
this.httpService
.postRequest(permitUrl() + apis.roles.delete, data)
.then((res) => {
this.getRoles();
this.mySwalToast({
title: "تبریک",
html: res.data.message,
icon: "success",
mySwalToast({
title: "تبریک",
html: res.data.message,
icon: "success",
});
});
});
}
});
},
@ -320,6 +330,7 @@ export default {
this.getRoles();
},
toggleRolesPanel(index = undefined) {
if (index !== undefined) {
if (this.prevSelectedItemIndex !== undefined)
this.roles[this.prevSelectedItemIndex].active = false;
@ -327,7 +338,7 @@ export default {
this.prevSelectedItemIndex = index;
this.roles[index].active = true;
this.selectedItemClone = structuredClone(this.roles[index]);
this.selectedItemClone = this.roles[index];
} else this.resetForm();
this.showPanel = true;
@ -375,9 +386,15 @@ export default {
});
},
async getProjects() {
return await ApiService.formData(permitApi.projects.list).then((res) => {
this.SET_PROJECT(res.data.data[0]);
});
return await this.httpService
.postRequest(permitUrl() + apis.projects.list)
.then((res) => {
console.log(
"🚀 ~ returnawaitthis.httpService.postRequest ~ res:",
res
);
this.SET_PROJECT(res.data[0]);
});
},
},
components: {

View File

@ -1,85 +1,94 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages user-role px-3 pb-0 pt-2">
<sub-header-with-select
canCreate="user-permission_new"
@open-form="showShareModal()"
:showProjectSelect="$attrs.showProjectSelect"
title="کاربران"
>
</sub-header-with-select>
<NuxtLayout name="default" :menu="adminMenu">
<div class="pages user-role px-3 pb-0 pt-2">
<sub-header-with-select
canCreate="user-permission_new"
@open-form="showShareModal()"
:showProjectSelect="$attrs.showProjectSelect"
title="کاربران"
>
</sub-header-with-select>
<div class="pages-content d-flex pb-0 pt-2">
<template v-if="canView">
<my-table
:tableActions="tableActions"
height="auto"
maxHeight="calc(100vh - 15em)"
class="my-table"
ref="userRolesTable"
:hasSearch="false"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="userRoles"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="toggleRolesPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
></my-table>
</template>
<no-data v-else>
<the-content-loading v-if="fetchingData"></the-content-loading>
<div class="pages-content d-flex pb-0 pt-2">
<template v-if="canView">
<my-table
:tableActions="tableActions"
height="auto"
maxHeight="calc(100vh - 15em)"
class="my-table"
ref="userRolesTable"
:hasSearch="false"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="userRoles"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="toggleRolesPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
></my-table>
</template>
<no-data v-else>
<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 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>
</div>
</no-data>
<div class="side-panel" v-if="showPanel">
<div class="side-panel-header">
<h6 class="">مدیریت نقش ها</h6>
</div>
</div>
</no-data>
<div class="side-panel" v-if="showPanel">
<div class="side-panel-header">
<h6 class="">مدیریت نقش ها</h6>
</div>
<div class="side-panel-content">
<Accordion
class="role-permission"
canEdit="user-permission_edit"
:user_id="user_id"
></Accordion>
<div class="side-panel-footer mt-4">
<div></div>
<div>
<button
@click.prevent="showPanel = false"
type="button"
class="btn btn-primary text-white"
>
بستن
</button>
<div class="side-panel-content">
<Accordion
class="role-permission"
canEdit="user-permission_edit"
:user_id="user_id"
></Accordion>
<div class="side-panel-footer mt-4">
<div></div>
<div>
<button
@click.prevent="showPanel = false"
type="button"
class="btn btn-primary text-white"
>
بستن
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<Share
@update-user-role="updateUserRole"
:roles="roles"
v-if="showModal"
:item="[]"
></Share>
</div>
</NuxtLayout>
<base-modal
v-if="showModal"
@close="closeModal"
:showHeaderCloseButton="true"
modalSize="modal-lg"
:modalTitle="modalTitle"
maxHeight="30em"
:showDeleteButton="false"
>
<Share
@update-user-role="updateUserRole"
:roles="roles"
:item="[]"
></Share>
</base-modal>
</div>
</NuxtLayout>
</template>
<script>
@ -101,6 +110,9 @@ export default {
layout: false,
});
},
created() {
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.checkPermisionBeforGetList();
this.getRoles();
@ -121,7 +133,9 @@ export default {
},
data() {
return {
adminMenu:adminMenu,
adminMenu: adminMenu,
httpService: {},
modalTitle: "اختصاص نقش به کاربر",
tableActions: [
{
showOutside: true,
@ -229,9 +243,10 @@ export default {
...{ project_id: this.projectGetter?.id },
};
ApiService.formData(apis.roleUser.AddRoleUser, formData)
this.httpService
.postRequest(permitUrl() + apis.roleUser.AddRoleUser, formData)
.then((response) => {
this.mySwalToast({
mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
@ -240,7 +255,7 @@ export default {
this.getUserRole();
})
.catch((err) => {
this.mySwalToast({
mySwalToast({
title: "خطا",
html: err.response.data.message ?? err.message,
icon: "error",
@ -269,15 +284,16 @@ export default {
const item = this.userRoles[index];
var vm = this;
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
if (result.isConfirmed) {
ApiService.formData(apis.permissions.deleteUserRole, {
project_id: vm.projectGetter?.id,
id: item.id,
})
this.httpService
.postRequest(permitUrl() + apis.permissions.deleteUserRole, {
project_id: vm.projectGetter?.id,
id: item.id,
})
.then((response) => {
vm.getUserRole();
})
@ -301,9 +317,10 @@ export default {
...this.sorting,
...this.pagination,
};
return await ApiService.formData(apis.permissions.listUserRole, payload)
return await this.httpService
.postRequest(permitUrl() + apis.permissions.listUserRole, payload)
.then((response) => {
this.userRoles = response.data.data;
this.userRoles = response.data;
this.userRoles.forEach((item, key) => {
item["role_name"] =
@ -319,17 +336,17 @@ export default {
},
};
this.userRoles[key].created_at = this.convertUnixToPersianDateTime(
this.userRoles[key].created_at = convertUnixToPersianDateTime(
item.created_at
);
});
this.pagination = { ...this.pagination, ...response.data.pagination };
this.pagination = { ...this.pagination, ...response.pagination };
})
.catch((err) => {
this.mySwalToast({
mySwalToast({
title: "خطا",
html: err.response.data.message ?? err.message,
html: err.response.message ?? err.message,
icon: "error",
});
})
@ -346,11 +363,14 @@ export default {
this.getRoles().then(() => {
this.showModal = true;
setTimeout(() => {
$("#share-modal").modal("show");
}, 500);
// setTimeout(() => {
// $("#share-modal").modal("show");
// }, 500);
});
},
closeModal() {
this.showModal = false;
},
updateList() {
this.resetPagination();
this.getUserRole();
@ -399,9 +419,12 @@ export default {
this.showPanel = true;
},
async getSections() {
return await ApiService.formData(apis.sections.list, {
project_id: this.projectGetter?.id,
});
return await this.httpService.postRequest(
permitUrl() + apis.sections.list,
{
project_id: this.projectGetter?.id,
}
);
},
collapseAllPanels() {
@ -425,11 +448,13 @@ export default {
clearTimeout(this.typingTimer);
},
async getRoles() {
return await ApiService.formData(apis.roles.list, {
project_id: this.projectGetter?.id,
}).then((res) => {
this.roles = res.data.data;
});
return await this.httpService
.postRequest(permitUrl() + apis.roles.list, {
project_id: this.projectGetter?.id,
})
.then((res) => {
this.roles = res.data;
});
},
checkPermisionBeforGetList() {
if (this.fetchingData) return;
@ -467,9 +492,11 @@ export default {
});
},
async getProjects() {
return await ApiService.formData(apis.projects.list).then((res) => {
this.SET_PROJECT(res.data.data[0]);
});
return await this.httpService
.postRequest(permitUrl() + apis.projects.list)
.then((res) => {
this.SET_PROJECT(res.data[0]);
});
},
},
components: {

View File

@ -1,9 +1,10 @@
<template>
<NuxtLayout name="default" :menu="adminMenu">
<div>
<!-- <header>
<the-navbar></the-navbar>
</header>
<the-sidebar :menu="menu"></the-sidebar> -->
</header> -->
<main class="pages-content-container">
<div class="pages-content mt-4 mt-lg-0">
@ -29,7 +30,8 @@
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<slot name="tableHeaderActions">
<template v-slot:tableHeaderActions>
<div class="dropdown">
<button
class="btn dropdown-toggle"
@ -60,7 +62,7 @@
</button>
</div>
</div>
</slot>
</template>
</my-table>
</div>
<no-data v-else>
@ -98,49 +100,57 @@
</div>
<div class="side-panel-content">
<users-search
<UsersSearch
v-if="showPanel"
:searchResults="users"
@on-send="searchUsers"
@set-as-admin="setAsAdmin"
></users-search>
></UsersSearch>
</div>
</div>
</div>
</div>
</main>
</div>
</NuxtLayout>
</template>
<script>
import { mapState, mapActions } from "pinia";
import menu from "~/json/admin/json/menu.json";
import adminMenu from "~/json/admin/json/menu.json";
// import menu from "~/json/admin/json/menu.json";
import adminApi from "~/apis/adminApi";
import permitApis from "~/apis/permitApi";
import { defineAsyncComponent } from "vue";
import { useCommonStore } from "~/stores/commonStore";
import { usePermitStore } from "~/stores/permitStore";
export default {
name: "groupsWithoutAdmin",
setup() {
definePageMeta({
name: "groupsWithoutAdmin",
layout: false,
});
},
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
// this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
this.httpService = useNuxtApp()["$http"];
},
mounted() {
this.checkPermisionBeforGetList();
},
data() {
return {
adminMenu: adminMenu,
searchType: "getGroupsWithoutAdmin",
groupsTranslation: {
getGroupsWithoutAdmin: "گروه های بدون مدیر",
getGroupsWithAdmin: "گروه های دارای مدیر",
},
groups: [],
menu: menu,
// menu: menu,
firstTimeSearching: false,
httpService: undefined,
tableActions: [
@ -210,10 +220,16 @@ export default {
prevSelectedItemIndex: undefined,
};
},
computed: {
...mapState(usePermitStore, ["projectGetter"]),
...mapState(useCommonStore, ["isSidebarCollapsed"]),
// ...mapState(["isSidebarCollapsed"]),
},
methods: {
...mapState(["isSidebarCollapsed"]),
...mapActions(["checkPermissions"]),
// ...mapState(["isSidebarCollapsed"]),
// ...mapActions(["checkPermissions"]),
...mapActions(useCommonStore, ["checkPermissions"]),
checkPermisionBeforGetList() {
if (this.fetchingData) return;
@ -328,7 +344,7 @@ export default {
this.loading = false;
});
this.mySwalToast({
mySwalToast({
html: res.message,
});
@ -405,7 +421,7 @@ export default {
const url = `${messageUrl()}/${adminApi.groups.delete}`;
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار",
html: "با حذف گروه، تمامی مسائل و پاسخ های آن نیز حذف خواهد شد.",
icon: "warning",
@ -417,7 +433,7 @@ export default {
// this.showPanel = false;
});
this.mySwalToast({
mySwalToast({
html: res.message,
});
});
@ -429,6 +445,11 @@ export default {
this.showPanel = true;
},
},
components: {
UsersSearch: defineAsyncComponent(() =>
import("@/components/admin/components/UsersSearch.vue")
),
},
};
</script>

View File

@ -1,118 +1,124 @@
<template>
<div class="main-users">
<!-- <header>
<the-navbar></the-navbar>
</header> -->
<!-- <the-sidebar :menu="menu"></the-sidebar> -->
<NuxtLayout name="default" :menu="adminMenu">
<div class="main-users">
<!-- <header>
<the-navbar></the-navbar>
</header> -->
<!-- <the-sidebar :menu="menu"></the-sidebar> -->
<main
class="pages-content-container"
<main class="pages-content-container">
<div class="pages-content mt-lg-0">
<div :class="{ 'd-flex': showPanel }">
<div v-if="canView">
<my-table
:tableActions="tableActions"
height="calc(100vh - 17em)"
:hasSearch="true"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="users"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@search="searchGroups"
@reset-form="searchUsers"
@delete-table-item="deleteItem"
@edit-table-item="toggleUsersPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<slot name="tableHeaderActions">
<button
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class="btn btn-primary add-user-btn"
type="button"
>
ایجاد
</button>
<span
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class="add-user-svg"
type="button"
>
<svg class="icon icon-Component-133--1">
<use xlink:href="#icon-Component-133--1"></use>
</svg>
</span>
</slot>
</my-table>
</div>
<no-data v-else>
<the-content-loading v-if="fetchingData"></the-content-loading>
>
<div class="pages-content mt-lg-0">
<div :class="{ 'd-flex': showPanel }">
<div v-if="canView">
<my-table
:tableActions="tableActions"
height="calc(100vh - 17em)"
:hasSearch="true"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="users"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@search="searchGroups"
@reset-form="searchUsers"
@delete-table-item="deleteItem"
@edit-table-item="toggleUsersPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<slot name="tableHeaderActions">
<button
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class="btn btn-primary add-user-btn"
type="button"
>
ایجاد
</button>
<span
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class=" add-user-svg"
type="button"
>
<svg class="icon icon-Component-133--1">
<use xlink:href="#icon-Component-133--1"></use>
</svg>
</span>
</slot>
</my-table>
</div>
<no-data v-else>
<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"
v-else
class="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>
عدم دسترسی
</div>
</div>
</div>
</no-data>
<div class="side-panel mx-5" v-if="showPanel">
<div class="side-panel-header d-flex mb-3 pb-3 border-bottom">
<h6 class="m-0">مدیریت کاربران</h6>
</no-data>
<div class="side-panel mx-5" v-if="showPanel">
<div class="side-panel-header d-flex mb-3 pb-3 border-bottom">
<h6 class="m-0">مدیریت کاربران</h6>
<button
@click.prevent="toggleUsersPanel(undefined)"
class="btn btn-outline-primary me-auto"
type="button"
>
x
</button>
</div>
<button
@click.prevent="toggleUsersPanel(undefined)"
class="btn btn-outline-primary me-auto"
type="button"
>
x
</button>
</div>
<div class="side-panel-content">
<new-user-form
:parentLoading="loading"
:userData="selectedItemClone"
@on-pass-by-emit="save"
></new-user-form>
<div class="side-panel-content">
<NewUserForm
:parentLoading="loading"
:userData="selectedItemClone"
@on-pass-by-emit="save"
></NewUserForm>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</main>
</div>
</NuxtLayout>
</template>
<script>
import apis from "~/apis/permitApi";
import { mapState, mapActions } from "pinia";
import adminMenu from "~/json/admin/json/menu.json";
import { defineAsyncComponent } from "vue";
import { useCommonStore } from "~/stores/commonStore";
import { usePermitStore } from "~/stores/permitStore";
import menu from "~/json/admin/json/menu.json";
// import menu from "~/json/admin/json/menu.json";
export default {
name: "adminUsers",
setup() {
definePageMeta({
name: "adminUsers",
layout: false,
});
},
beforeMount() {
this.httpService = new HttpService(
import.meta.env.VITE_BASE_URL + loginUrl()
);
// this.httpService = new HttpService(
// import.meta.env.VITE_BASE_URL + loginUrl()
// );
this.httpService = useNuxtApp()["$http"];
// this.httpService + loginUrl();
},
mounted() {
this.checkPermisionBeforGetList();
@ -125,7 +131,8 @@ export default {
// },
data() {
return {
menu: menu,
adminMenu: adminMenu,
// menu: menu,
firstTimeSearching: false,
httpService: undefined,
tableActions: [
@ -231,11 +238,13 @@ export default {
};
},
computed: {
...mapState("permit", ["projectGetter"]),
...mapState(["isSidebarCollapsed"]),
...mapState(usePermitStore, ["projectGetter"]),
...mapState(useCommonStore, ["isSidebarCollapsed"]),
// ...mapState(["isSidebarCollapsed"]),
},
methods: {
...mapActions(["checkPermissions"]),
// ...mapActions(["checkPermissions"]),
...mapActions(useCommonStore, ["checkPermissions"]),
checkPermisionBeforGetList() {
if (this.fetchingData) return;
this.fetchingData = true;
@ -283,7 +292,8 @@ export default {
url = url.replace("{{sortby}}", this.sorting.sortby);
url = url.replace("{{sortorder}}", this.sorting.sortorder);
return await this.httpService.getRequest(url).then((res) => {
return await this.httpService.getRequest(loginUrl() + url).then((res) => {
this.users = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
});
@ -301,7 +311,7 @@ export default {
this.loading = false;
});
this.mySwalToast({
mySwalToast({
html: res.message,
});
@ -321,7 +331,7 @@ export default {
id: userId,
};
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار",
html: "هشدار!!!!",
icon: "warning",
@ -335,7 +345,7 @@ export default {
this.showPanel = false;
});
this.mySwalToast({
mySwalToast({
html: res.message,
});
});
@ -395,7 +405,11 @@ export default {
this.showPanel = false;
},
},
components: {
NewUserForm: defineAsyncComponent(() =>
import("@/components/admin/components/NewUserForm.vue")
),
},
};
</script>
<style scoped lang="scss">

View File

@ -1,106 +1,113 @@
<template>
<div>
<!-- <header>
<NuxtLayout name="default" :menu="adminMenu">
<div>
<!-- <header>
<the-navbar></the-navbar>
</header>
<the-sidebar :menu="menu"></the-sidebar> -->
<main class="pages-content-container">
<div class="pages-content mt-4 mt-lg-0">
<div class="p-3" :class="{ 'd-flex': showPanel }">
<div v-if="canView">
<my-table
:tableActions="tableActions"
height="calc(100vh - 17em)"
:hasSearch="true"
maxHeight="calc(100dvh - 5em)"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="users"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@search="searchGroups"
@reset-form="searchUsers"
@delete-table-item="deleteItem"
@edit-table-item="toggleUsersPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<template #tableHeaderActions>
<main class="pages-content-container">
<div class="pages-content mt-4 mt-lg-0">
<div class="p-3" :class="{ 'd-flex': showPanel }">
<div v-if="canView">
<my-table
:tableActions="tableActions"
height="calc(100vh - 17em)"
:hasSearch="true"
maxHeight="calc(100dvh - 5em)"
:paginationInfo="pagination"
:sortingInfo="sorting"
:items="users"
:fetchingData="fetchingData"
:tableColumns="tableColumns"
:totalPages="pagination.pages"
@search="searchGroups"
@reset-form="searchUsers"
@delete-table-item="deleteItem"
@edit-table-item="toggleUsersPanel"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<template #tableHeaderActions>
<button
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class="btn btn-primary"
type="button"
>
ایجاد
</button>
</template>
</my-table>
</div>
<no-data v-else>
<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>
</div>
</no-data>
<div class="side-panel mx-5" v-if="showPanel">
<div class="side-panel-header d-flex mb-3 pb-3 border-bottom">
<h6 class="m-0">مدیریت کاربران</h6>
<button
v-if="!showPanel"
@click.prevent="openCreatePanel()"
class="btn btn-primary"
@click.prevent="toggleUsersPanel(undefined)"
class="btn btn-outline-primary me-auto"
type="button"
>
ایجاد
x
</button>
</template>
</my-table>
</div>
<no-data v-else>
<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>
</div>
</no-data>
<div class="side-panel mx-5" v-if="showPanel">
<div class="side-panel-header d-flex mb-3 pb-3 border-bottom">
<h6 class="m-0">مدیریت کاربران</h6>
<button
@click.prevent="toggleUsersPanel(undefined)"
class="btn btn-outline-primary me-auto"
type="button"
>
x
</button>
</div>
<div class="side-panel-content">
<new-user-form
:parentLoading="loading"
:userData="selectedItemClone"
@on-pass-by-emit="save"
></new-user-form>
<div class="side-panel-content">
<NewUserForm
:parentLoading="loading"
:userData="selectedItemClone"
@on-pass-by-emit="save"
></NewUserForm>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</main>
</div>
</NuxtLayout>
</template>
<script>
import apis from "~/apis/permitApi";
import { mapState, mapActions } from "pinia";
import menu from "~/json/admin/json/menu.json";
import adminMenu from "~/json/admin/json/menu.json";
// import menu from "~/json/admin/json/menu.json";
import { defineAsyncComponent } from "vue";
import { useCommonStore } from "~/stores/commonStore";
import { usePermitStore } from "~/stores/permitStore";
export default {
name: "userModifications",
setup() {
definePageMeta({
name: "userModifications",
layout: false,
});
},
beforeMount() {
this.httpService = new HttpService(
import.meta.env.VITE_BASE_URL + loginUrl()
);
// this.httpService = new HttpService(
// import.meta.env.VITE_BASE_URL + loginUrl()
// );
this.httpService = useNuxtApp()["$http"];
// this.httpService + loginUrl();
},
mounted() {
this.checkPermisionBeforGetList();
@ -113,7 +120,8 @@ export default {
// },
data() {
return {
menu: menu,
adminMenu: adminMenu,
// menu: menu,
firstTimeSearching: false,
httpService: undefined,
tableActions: [
@ -218,11 +226,15 @@ export default {
prevSelectedItemIndex: undefined,
};
},
computed: {
...mapState(usePermitStore, ["projectGetter"]),
...mapState(useCommonStore, ["isSidebarCollapsed"]),
},
methods: {
...mapState(["isSidebarCollapsed"]),
// ...mapState(["isSidebarCollapsed"]),
...mapActions(["checkPermissions"]),
// ...mapActions(["checkPermissions"]),
...mapActions(useCommonStore, ["checkPermissions"]),
checkPermisionBeforGetList() {
if (this.fetchingData) return;
this.fetchingData = true;
@ -270,7 +282,8 @@ export default {
url = url.replace("{{sortby}}", this.sorting.sortby);
url = url.replace("{{sortorder}}", this.sorting.sortorder);
return await this.httpService.getRequest(url).then((res) => {
return await this.httpService.getRequest(loginUrl()+ url).then((res) => {
console.log("🚀 ~ returnawaitthis.httpService.getRequest ~ res:", res)
this.users = res.data;
this.pagination = { ...this.pagination, ...res.pagination };
});
@ -281,7 +294,7 @@ export default {
const url = formData.id ? apis.users.update : apis.users.create;
formData;
// formData;
this.httpService
.postRequest(url, formData)
.then((res) => {
@ -289,7 +302,7 @@ export default {
this.loading = false;
});
this.mySwalToast({
mySwalToast({
html: res.message,
});
@ -309,7 +322,7 @@ export default {
id: userId,
};
this.mySwalConfirm({
mySwalConfirm({
title: "هشدار",
html: "هشدار!!!!",
icon: "warning",
@ -323,7 +336,7 @@ export default {
this.showPanel = false;
});
this.mySwalToast({
mySwalToast({
html: res.message,
});
});
@ -383,7 +396,11 @@ export default {
this.showPanel = false;
},
},
components: {
NewUserForm: defineAsyncComponent(() =>
import("@/components/admin/components/NewUserForm.vue")
),
},
};
</script>
<style scoped lang="scss">

View File

@ -1,89 +0,0 @@
<template>
<div>
<the-content-loading v-if="fetchingData"></the-content-loading>
<my-quill :parentButtonLoading="buttonLoading" v-else :tinyText="tinyText" @input="onSave"
@on-save="onSave"></my-quill>
</div>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
export default {
name: "dataSettingAboutUs",
setup() {
definePageMeta({
name: "dataSettingAboutUs",
});
},
data() {
return {
buttonLoading: false,
tinyText: '',
fetchingData: false,
data: undefined,
};
},
methods: {
getData() {
var vm = this;
this.fetchingData = true;
var url = settingsApi.app.getByKey;
url = url.replace("{{key_option}}", "about_text");
// let url = apis.admin.get.replace('{{system}}', this.$route.meta.apiKey)
ApiService.getRequest(url)
.then((response) => {
vm.fetchingData = false;
this.tinyText = response.data.hits.hits[0]._source.value;
this.data = response.data.hits.hits[0]._source;
})
.catch((error) => {
}).finally(() => {
vm.fetchingData = false;
})
},
onSave(newContent) {
if (this.buttonLoading) return;
this.buttonLoading = true;
// var url = apis.admin.save;
// const payload = { ...this.data, ...{ value: newContent } }
var url = settingsApi.app.saveByKey;
url = url.replace("{{key_option}}", "about_text");
const payload = { value: newContent }
ApiService.postRequest(url, payload)
.then((response) => {
this.mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
});
})
.catch((error) => {
}).finally(() => {
this.buttonLoading = false;
})
}
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
};
</script>

View File

@ -1,293 +0,0 @@
<template>
<div>
<Multiselect
:allow-empty="false"
:searchable="true"
:close-on-select="true"
:show-labels="false"
:value="value"
:options="options"
class="multi mb-2"
@select="select"
label="label"
track-by="key"
placeholder="دسته"
:hide-selected="false"
:max-height="200"
:max-width="200"
>
</Multiselect>
<MyTable
height="auto"
maxHeight="calc(100vh - 9em)"
class="my-table"
ref="sectionsTable"
:hasSearch="false"
:tableActions="tableActions"
:items="sections"
:tableColumns="tableColumns"
:paginationInfo="pagination"
:totalPages="pagination.pages"
@delete-table-item="deleteItem"
@edit-table-item="editTableItem"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
<!-- :fetchingData="fetchingData" :totalPages="pagination.pages"
@delete-table-item="deleteItem" @edit-table-item="toggleRolesPanel"
@page-changed="pageChanged" @page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged" -->
<!-- :paginationInfo="pagination"
:sortingInfo="sorting -->
</MyTable>
<base-modal
v-if="openSubjectForm"
modalSize="modal-lg"
:hasFooter="false"
@close="closeModal"
>
<component
:is="slotComponentName"
:editList="editList"
@close="closeModal"
></component>
</base-modal>
</div>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
import { mapState, mapActions } from "pinia";
import searchApi from "~/apis/searchApi";
import { useStorage } from "@vueuse/core";
export default {
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(["organNameGetter"]),
myActiveSchema() {
return this.helpSchemaGetter?.find((item) => {
return item.key == "help";
});
},
},
mounted() {
let localStoageHelpSchema = useStorage("settingSchema",undefined).value;
if (localStoageHelpSchema) {
let helpSchema = JSON.parse(localStoageHelpSchema);
this.helpSchemaSetter(helpSchema);
this.options = this.myActiveSchema?.category;
this.value = this.myActiveSchema?.category[0];
} else {
this.getSchemas();
}
this.getList();
},
data() {
return {
options: [{ name: "جستجو" }, { name: "محتوا" }, { name: "مطالعه" }],
httpService: undefined,
value: "",
editList: "",
slotComponentName: "",
modalTitle: "",
openSubjectForm: false,
listSections: [],
sections: [],
tableActions: [
{
showOutside: true,
show: true,
icon: "tavasi tavasi-Component-242--1",
title: this.$t("Edit"),
to: {
name: "undefined",
},
selected: false,
disabled: false,
howToOpen: "",
href: "",
class: "edit-btn",
action: "edit-table-item",
can: "item-info_edit",
},
{
showOutside: true,
show: true,
icon: "tavasi tavasi-Component-295--1",
title: this.$t("Delete"),
to: {
name: "undefined",
},
selected: false,
disabled: false,
howToOpen: "",
href: "",
class: "delete-btn",
action: "delete-table-item",
can: "item-list_delete",
},
],
tableColumns: [
{
isLink: true,
key: "title",
title: "عنوان سوال",
width: "1",
},
{
key: "description",
title: "توضیحات",
width: "6",
},
],
pagination: {
page: 1,
pages: 0,
total: 0,
offset: 0,
limit: 10,
},
sorting: "",
};
},
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
},
methods: {
...mapActions("search", ["helpSchemaSetter"]),
openModal(componentName, title) {
this.openSubjectForm = true;
this.slotComponentName = componentName;
this.modalTitle = title;
setTimeout(() => {
$("#meta-item-modal").modal(
{ backdrop: "static", keyboard: false },
"show"
);
}, 500);
},
closeModal() {
$("#base-modal").modal({
show: false,
});
setTimeout(() => {
this.openSubjectForm = false;
this.getList();
}, 1000);
},
editTableItem(item) {
this.editList = this.listSections[item];
this.openModal("editModalItem", "فیلتر ها");
},
deleteItem(item) {
this.mySwalConfirm({
title: "هشدار!!!",
html: "تمامی اطلاعات پاک خواهد. آیا مطمئن هستید؟ ",
}).then((result) => {
if (result.isConfirmed) {
var id = this.listSections[item]?._id;
let url = settingsApi.help.delete;
url = url.replace("{{id}}", id);
this.httpService.postRequest(url).then((response) => {
this.mySwalToast({
title: "با موفقیت حذف شد",
// html: response.data.message,
icon: "success",
});
this.getList();
});
}
});
},
getList() {
let url = settingsApi.help.list;
url = url.replace("{{key_option}}", this.value?.key);
url = url.replace("{{offset}}", this.pagination?.offset);
url = url.replace("{{limit}}", this.pagination?.limit);
this.httpService.getRequest(url).then((response) => {
let list = response.hits?.hits;
this.listSections = list;
if (this.sections.length >= 0) this.sections = [];
// this.sections = response.hits.hits;
list.forEach((element) => {
this.sections.push(element?._source.meta);
});
const total = response.hits.total.value;
const pages = Math.ceil(total / this.pagination.limit);
const pagination = {
total: total,
pages: pages == 0 ? 1 : pages,
};
this.pagination = { ...this.pagination, ...pagination };
// this.pagination = { ...this.pagination, ...response.pagination };
});
},
getSchemas() {
this.httpService
.postRequest(searchApi.schema.list, {
organ: this.organNameGetter,
system: "setting",
build_state: buildState(),
})
.then((response) => {
this.helpSchemaSetter(response.data?.setting);
this.options = this.myActiveSchema?.category;
this.value = this.myActiveSchema?.category[0];
// this.options = response;
});
},
select(e) {
this.value = e;
this.getList();
},
resetPagination() {
this.pagination = {
pages: 0,
total: 0,
page: 1,
offset: 0,
limit: 10,
};
},
pageLimitChanged(paging) {
this.resetPagination();
this.pagination.limit = paging?.limit;
this.getList();
},
pageChanged(paging) {
let page = paging.pageNumber;
page -= 1;
this.pagination.offset = page * paging.limit;
this.pagination.limit = paging.limit;
this.pagination.page = paging.pageNumber;
this.getList();
},
sortChanged(sorting) {
this.pagination.page = this.pagination.offset = 0;
this.sorting = sorting;
this.getList();
},
},
};
</script>
<style scoped>
.multi {
width: 200px;
border: 2px solid rgb(127, 170, 170);
border-radius: 0.5rem;
}
</style>

View File

@ -1,219 +0,0 @@
<template>
<div class="page">
<div class="container">
<form>
<div class="form-row">
<div class="col-3">
<label for=""> انتخاب بخش:</label>
<multiselect
:allow-empty="false"
:searchable="true"
:close-on-select="true"
:show-labels="false"
:value="value"
:options="options"
class="multi"
@select="select"
label="label"
track-by="key"
placeholder="دسته"
:hide-selected="false"
:max-height="200"
>
</multiselect>
</div>
</div>
<div class="form-row">
<div class="col-6">
<label for="">عنوان سوال:</label>
<input
type="text"
class="form-control"
placeholder="عنوان سوال را کوتاه و واضح وارد نمایید"
v-model="title"
/>
</div>
<div class="col-6">
<label for="">نشانی صفحه:</label>
<input
type="text"
class="form-control"
placeholder="نشانی از همین سامانه انتخاب کنید"
v-model="link"
/>
</div>
</div>
<div class="form-row">
<div class="col">
<label for="">توضیح کوتاه:</label>
<input
type="text"
placeholder="توضیح مختصر حداکثر یک خط باشد"
v-model="description"
maxlength="500"
/>
</div>
</div>
<div class="form-row">
<div class="col">
<label for="" class="mt-2">توضیح مفصل:</label>
<VueEditor
dir="rtl"
v-model="editorData"
:editorOptions="editorOptions"
></VueEditor>
</div>
</div>
</form>
<button class="btn-save" @click="saveData">ذخیره</button>
</div>
</div>
</template>
<script>
import searchApi from "~/apis/searchApi";
import settingsApi from "~/apis/settingsApi";
import { VueEditor } from "vue2-editor";
import { mapState, mapActions } from "pinia";
import { useStorage } from "@vueuse/core";
export default {
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
},
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(["organNameGetter"]),
},
mounted() {
let localStoageHelpSchema = useStorage("settingSchema",undefined).value;
if (localStoageHelpSchema) {
let helpSchema = JSON.parse(localStoageHelpSchema);
this.helpSchemaSetter(helpSchema);
this.options = this.helpSchemaGetter[0].category;
} else this.getSchemas();
},
data() {
return {
value: "",
editorData: "",
title: "",
link: "",
description: "",
fullDesc: "",
httpService: undefined,
options: [{ name: "جستجو" }, { name: "محتوا" }, { name: "مطالعه" }],
editorOptions: {
formats: {
direction: "rtl",
align: "right",
},
placeholder: "توضیحات...",
// readOnly: true,
// theme: "snow",
},
};
},
methods: {
...mapActions("search", ["helpSchemaSetter"]),
select(e) {
this.value = e;
},
getSchemas() {
this.httpService
.postRequest(searchApi.schema.list, {
organ: this.organNameGetter,
system: "setting",
build_state: buildState(),
})
.then((response) => {
this.helpSchemaSetter(response.data.setting);
this.options = this.helpSchemaGetter[0].category;
// this.options = response;
});
},
saveData() {
var origin = location.origin;
let cleaned = this.link;
if (this.link.startsWith(origin) || this.link == "") {
cleaned = this.link.replace(origin, "");
} else {
let errorMessage = "نشانی پیوند باید با " + origin + "شروع شود";
this.mySwalToast({
title: errorMessage,
// html: response.data.message,
icon: "error",
timer: 7000,
});
return "";
}
let payload = {
value_key: this.value.key,
value: this.editorData,
meta : {
title: this.title,
link: cleaned,
description: this.description,
}
}
this.httpService
.postRequest(settingsApi.help.addItem, payload)
.then((response) => {
this.mySwalToast({
title: "با موفقیت ثبت شد",
// html: response.data.message,
icon: "success",
});
this.resetItem();
// this.helpSchemaSetter(response.data.setting);
// this.options = response;
});
},
resetItem() {
this.title = "";
this.link = "";
this.description = "";
this.editorData = "";
},
},
};
</script>
<style scoped lang="scss">
input {
border-radius: 0.5rem;
border: 2px solid rgb(127, 170, 170);
font-size: 14px;
height: 3em;
width: 100%;
&::placeholder {
color: #a7a098;
}
}
.multi {
// width: 200px;
border: 2px solid rgb(127, 170, 170);
border-radius: 0.5rem;
}
.btn-save {
width: 100px;
height: 2.5em;
float: left;
background-color: white;
margin-top: 0.8em;
border-radius: 0.5rem;
border: 2px solid rgb(127, 170, 170);
}
.page {
height: calc(100vh - 5em);
}
</style>

View File

@ -1,230 +0,0 @@
<template>
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div v-if="canView">
<div class="user__container">
<div class="d-flex justify-content-between align-items-center">
<div>
<h3>
{{ $t("Notifications") }}
</h3>
<p class="text__light text__13">
شما {{ list?.length }} اعلان خوانده نشده دارید.
</p>
</div>
<div>
<button-component
@click="openModal"
type="button"
classes="btn-primary"
buttonText="اعلان جدید"
title="اعلان جدید"
>
</button-component>
</div>
</div>
<ul class="nav nav-tabs">
<li class="nav-item">
<button
title="همه"
type="button"
@click.prevent="filterNotifications('all')"
class="btn nav-link"
:class="{
active: activeTab == 'all',
}"
>
<span class="badge badge-light">{{ counts?.all?.count }}</span>
همه
</button>
</li>
<li class="nav-item">
<button
title="جدید"
type="button"
@click.prevent="filterNotifications('new')"
class="btn nav-link"
:class="{
active: activeTab == 'new',
}"
>
<span class="badge badge-light">{{ counts?.new?.count }}</span>
جدید
</button>
</li>
<li class="nav-item">
<button
title="خوانده نشده ها"
type="button"
@click.prevent="filterNotifications('unseen')"
class="btn nav-link"
:class="{
active: activeTab == 'unseen',
}"
>
<span class="badge badge-light">{{ counts?.unseen?.count }}</span>
خوانده نشده ها
</button>
</li>
<li class="nav-item">
<button
title="خوانده شده ها"
type="button"
@click.prevent="filterNotifications('seen')"
class="btn nav-link"
:class="{
active: activeTab == 'seen',
}"
>
<span class="badge badge-light">{{ counts?.seen?.count }}</span>
خوانده شده ها
</button>
</li>
</ul>
<the-content-loading
class="absolute-positioning"
v-if="fetchingData"
></the-content-loading>
<div v-else>
<div v-if="list && list.length">
<div class="notif-list firefox-scrollbar">
<notification-item
v-for="(item, index) in list"
:item="item"
:index="index"
:key="item._id"
@getList="getList()"
@go-to-notification-show-page="
goToNotificationShowPage(item)
"
></notification-item>
</div>
<jahat-pagination
v-if="pagination.total"
:paginationInfo="pagination"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
</jahat-pagination>
</div>
<no-data v-else></no-data>
</div>
</div>
</div>
<no-data v-else>
<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 ml-1 text__32"
></span>
عدم دسترسی
</div>
</div>
</no-data>
</div>
</div>
<base-modal
v-if="showModal"
modalSize="modal-lg"
modalTitle="اعلان جدید"
:hasFooter="false"
@close="closeModal"
>
<admin-notification-form
ref="tabFormBuilder"
:formData="notificationItem"
@close-modal="closeModal"
></admin-notification-form>
</base-modal>
</div>
</template>
<script>
import notificationMixin from "~/mixins/notifications/notificationMixin";
export default {
extends: notificationMixin,
mounted() {
// this.canView = true;
this.checkPermisionBeforGetList("notification_edit").then(() => {
this.getList();
this.numberOfMark();
});
},
// watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
// },
data() {
return {
showModal: false,
};
},
methods: {
onEditItem(item, index) {
this.notificationItem = item;
this.openModal();
},
onDeleteItem(item) {
this.mySwalConfirm({
title: "هشدار!!!",
html: "از حذف این مورد مطمئن هستید؟",
}).then((result) => {
if (result.isConfirmed) {
this.deleteItem(item).then(() => {
setTimeout(() => {
this.getList();
}, 1000);
});
}
});
},
openModal() {
this.showModal = true;
setTimeout(() => {
$("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
}, 500);
},
closeModal(isCreate = false) {
$("#base-modal").modal("hide");
if (isCreate)
setTimeout(() => {
this.showModal = false;
this.notificationItem = undefined;
this.getList();
}, 1000);
else
setTimeout(() => {
this.showModal = false;
this.notificationItem = undefined;
this.getList();
}, 500);
},
},
};
</script>

View File

@ -1,90 +0,0 @@
<template>
<div>
<the-content-loading v-if="fetchingData"></the-content-loading>
<my-quill :parentButtonLoading="buttonLoading" v-else :tinyText="tinyText" @input="onSave"
@on-save="onSave"></my-quill>
</div>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
export default {
name: "dataSettingContactUs",
setup() {
definePageMeta({
name: "dataSettingContactUs",
});
},
data() {
return {
buttonLoading: false,
tinyText: '',
fetchingData: false,
data: undefined,
};
},
methods: {
getData() {
var vm = this;
this.fetchingData = true;
var url = settingsApi.app.getByKey;
url = url.replace("{{key_option}}", "conect_text");
// let url = apis.admin.get.replace('{{system}}', this.$route.meta.apiKey)
ApiService.getRequest(url)
.then((response) => {
vm.fetchingData = false;
this.tinyText = response.data.hits.hits[0]._source.value;
this.data = response.data.hits.hits[0]._source;
})
.catch((error) => {
}).finally(() => {
vm.fetchingData = false;
})
},
onSave(newContent) {
if (this.buttonLoading) return;
this.buttonLoading = true;
// var url = apis.admin.save;
// const payload = { ...this.data, ...{ value: newContent } }
var url = settingsApi.app.saveByKey;
url = url.replace("{{key_option}}", "conect_text");
const payload = { value: newContent }
ApiService.postRequest(url, payload)
.then((response) => {
this.mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
});
})
.catch((error) => {
}).finally(() => {
this.buttonLoading = false;
})
}
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
};
</script>

View File

@ -1,103 +0,0 @@
<template>
<div>
<the-content-loading v-if="fetchingData"></the-content-loading>
<div v-else>
<form v-if="properties.length" class="form" @submit.prevent="onSubmit()">
<div v-for="(property, index) in properties" :key="property.title" class="form-row form-group">
<label class="col-1" :for="'ta' + index">{{ property.title }} </label>
<div class="col">
<textarea class="form-control" :id="'ta' + index" :name="'ta' + index" :placeholder="property.title"
v-model.trim="property.keys" rows="1"></textarea>
</div>
</div>
<div class="form-row form-group mt-4">
<div class="col d-flex">
<button-component classes="btn-outline-primary" type="submit" :buttonText="'ذخیره'"
:buttonLoading="buttonLoading"></button-component>
</div>
</div>
</form>
<no-data v-else />
</div>
</div>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
export default {
data() {
return {
stopWords: '',
fetchingData: false,
buttonLoading: false,
properties: [],
payload: {},
};
},
computed: {
},
methods: {
getData() {
if (this.fetchingData) return;
this.fetchingData = true;
var url = settingsApi.app.getByKey;
url = url.replace("{{key_option}}", "search_amplify");
// let url = apis.admin.get.replace('{{system}}', this.$route.meta.apiKey)
ApiService.getRequest(url)
.then((response) => {
this.payload = response.data.hits.hits[0]._source;
this.properties = JSON.parse(response.data.hits.hits[0]._source.value);
})
.catch((error) => {
}).finally(() => {
this.fetchingData = false;
})
},
onSubmit() {
if (this.buttonLoading) return;
this.buttonLoading = true;
// var url = apis.admin.save;
// const payload = { ...this.payload, ...{ value: JSON.stringify(this.properties) } }
var url = settingsApi.app.saveByKey;
url = url.replace("{{key_option}}", "search_amplify");
const payload = { value: JSON.stringify(this.properties) }
ApiService.postRequest(url, payload)
.then((response) => {
this.mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
});
})
.catch((error) => {
}).finally(() => {
this.buttonLoading = false;
})
}
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
};
</script>

View File

@ -1,107 +0,0 @@
<template>
<div>
<the-content-loading v-if="fetchingData"></the-content-loading>
<form v-else @submit.prevent="onSave()">
<div class="form-group">
<!-- <label for="stop-words"></label> -->
<textarea
v-model="stopWords"
class="form-control"
id="stop-words"
rows="10"
style="height: auto"
></textarea>
</div>
<button-component
type="submit"
classes="btn-primary"
:buttonText="saveButtonText"
>
</button-component>
</form>
</div>
</template>
<script>
import settingsApi from "~/apis/settingsApi";
export default {
props: {
saveButtonText: {
default: "ذخیره",
},
},
data() {
return {
stopWords: "",
fetchingData: false,
data: undefined,
buttonLoading: false,
};
},
methods: {
getData() {
var vm = this;
this.fetchingData = true;
var url = settingsApi.app.getByKey;
url = url.replace("{{key_option}}", "words_stop");
// let url = apis.admin.get.replace("{{system}}", this.$route.meta.apiKey);
ApiService.getRequest(url)
.then((response) => {
vm.fetchingData = false;
this.stopWords = response.data.hits.hits[0]._source.value;
this.data = response.data.hits.hits[0]._source;
})
.finally(() => {
vm.fetchingData = false;
});
},
onSave() {
if (this.buttonLoading) return;
this.buttonLoading = true;
// var url = apis.admin.save;
// const payload = { ...this.data, ...{ value: this.stopWords } };
var url = settingsApi.app.saveByKey;
url = url.replace("{{key_option}}", "words_stop");
const payload = { value: this.stopWords }
ApiService.postRequest(url, payload)
.then((response) => {
this.mySwalToast({
title: "تبریک",
html: response.data.message,
icon: "success",
});
})
.finally(() => {
this.buttonLoading = false;
});
},
},
mounted() {
this.getData();
},
watch: {
// $route: {
// handler: function () {
// this.$store.state.collapsed = false;
// },
// deep: true,
// immediate: true,
// },
},
};
</script>

View File

@ -1,224 +0,0 @@
<template>
<div class="page">
<div class="container">
<form>
<div class="form-row">
<div class="col-3">
<label for=""> انتخاب بخش:</label>
<multiselect
:allow-empty="false"
:searchable="true"
:close-on-select="true"
:show-labels="false"
:value="value"
:options="options"
class="multi"
@select="select"
label="label"
track-by="key"
placeholder="دسته"
:hide-selected="false"
:max-height="200"
>
</multiselect>
</div>
</div>
<div class="form-row">
<div class="col-6">
<label for="">عنوان سوال:</label>
<input
type="text"
class="form-control"
placeholder="عنوان سوال را کوتاه و واضح وارد نمایید"
v-model="title"
/>
</div>
<div class="col-6">
<label for="">نشانی صفحه:</label>
<input
type="text"
class="form-control"
placeholder="نشانی از همین سامانه انتخاب کنید"
v-model="link"
/>
</div>
</div>
<div class="form-row">
<div class="col">
<label for="">توضیح کوتاه:</label>
<input
type="text"
placeholder="توضیح مختصر حداکثر یک خط باشد"
v-model="description"
maxlength="500"
/>
</div>
</div>
<div class="form-row">
<div class="col">
<label for="" class="mt-2">توضیح مفصل:</label>
<!-- <VueEditor
dir="rtl"
v-model="editorData"
:editorOptions="editorOptions"
></VueEditor> -->
</div>
</div>
</form>
<button class="btn-save" @click="saveData">ذخیره</button>
</div>
</div>
</template>
<script>
import searchApi from "~/apis/searchApi";
import settingsApi from "~/apis/settingsApi";
// import { VueEditor } from "vue2-editor";
import { mapState, mapActions } from "pinia";
import { useStorage } from "@vueuse/core";
export default {
name: "adminGuides",
setup() {
definePageMeta({
name: "adminGuides",
});
},
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
},
computed: {
...mapState(useSearchStore, ["helpSchemaGetter"]),
...mapState(["organNameGetter"]),
},
mounted() {
let localStoageHelpSchema = useStorage("settingSchema",undefined).value;
if (localStoageHelpSchema) {
let helpSchema = JSON.parse(localStoageHelpSchema);
this.helpSchemaSetter(helpSchema);
this.options = this.helpSchemaGetter[0].category;
} else this.getSchemas();
},
data() {
return {
value: "",
editorData: "",
title: "",
link: "",
description: "",
fullDesc: "",
httpService: undefined,
options: [{ name: "جستجو" }, { name: "محتوا" }, { name: "مطالعه" }],
editorOptions: {
formats: {
direction: "rtl",
align: "right",
},
placeholder: "توضیحات...",
// readOnly: true,
// theme: "snow",
},
};
},
methods: {
...mapActions("search", ["helpSchemaSetter"]),
select(e) {
this.value = e;
},
getSchemas() {
this.httpService
.postRequest(searchApi.schema.list, {
organ: this.organNameGetter,
system: "setting",
build_state: buildState(),
})
.then((response) => {
this.helpSchemaSetter(response.data.setting);
this.options = this.helpSchemaGetter[0].category;
// this.options = response;
});
},
saveData() {
var origin = location.origin;
let cleaned = this.link;
if (this.link.startsWith(origin) || this.link == "") {
cleaned = this.link.replace(origin, "");
} else {
let errorMessage = "نشانی پیوند باید با " + origin + "شروع شود";
this.mySwalToast({
title: errorMessage,
// html: response.data.message,
icon: "error",
timer: 7000,
});
return "";
}
let payload = {
value_key: this.value.key,
value: this.editorData,
meta : {
title: this.title,
link: cleaned,
description: this.description,
}
}
this.httpService
.postRequest(settingsApi.help.addItem, payload)
.then((response) => {
this.mySwalToast({
title: "با موفقیت ثبت شد",
// html: response.data.message,
icon: "success",
});
this.resetItem();
// this.helpSchemaSetter(response.data.setting);
// this.options = response;
});
},
resetItem() {
this.title = "";
this.link = "";
this.description = "";
this.editorData = "";
},
},
};
</script>
<style scoped lang="scss">
input {
border-radius: 0.5rem;
border: 2px solid rgb(127, 170, 170);
font-size: 14px;
height: 3em;
width: 100%;
&::placeholder {
color: #a7a098;
}
}
.multi {
// width: 200px;
border: 2px solid rgb(127, 170, 170);
border-radius: 0.5rem;
}
.btn-save {
width: 100px;
height: 2.5em;
float: left;
background-color: white;
margin-top: 0.8em;
border-radius: 0.5rem;
border: 2px solid rgb(127, 170, 170);
}
.page {
height: calc(100vh - 5em);
}
</style>

View File

@ -147,7 +147,7 @@ export default {
cleaned = this.link.replace(origin, "");
} else {
let errorMessage = "نشانی پیوند باید با " + origin + "شروع شود";
this.mySwalToast({
mySwalToast({
title: errorMessage,
// html: response.data.message,

View File

@ -0,0 +1,33 @@
import { defineNuxtPlugin } from '#app';
import Swal from 'sweetalert2';
import 'sweetalert2/dist/sweetalert2.min.css';
export default defineNuxtPlugin(nuxtApp => {
const mySwalToast = (options:any) => {
return Swal.fire({
toast: true,
position: 'bottom-end',
showConfirmButton: false,
timerProgressBar: true,
timer: 5000,
icon: 'success',
...options,
});
};
const mySwalConfirm = (options:any) => {
return Swal.fire({
title: 'هشدار',
text: 'آیا مطمئن هستید؟',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'تایید',
cancelButtonText: 'انصراف',
...options,
});
};
// به جای استفاده از `provide()`
nuxtApp.$mySwalToast = mySwalToast;
nuxtApp.$mySwalConfirm = mySwalConfirm;
});

View File

@ -0,0 +1,7 @@
import { defineNuxtPlugin } from '#app'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('QuillEditor', QuillEditor)
})

@ -1 +1 @@
Subproject commit 631e6cce32be9fb2ffe572fe35e5543d3597ba80
Subproject commit 49b47bb97fa7394c84ba16a340e08c1fac5384a1

286
yarn.lock
View File

@ -2234,6 +2234,14 @@
dependencies:
vue-demi "^0.13.11"
"@vueup/vue-quill@^1.2.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@vueup/vue-quill/-/vue-quill-1.2.0.tgz"
integrity sha512-kd5QPSHMDpycklojPXno2Kw2JSiKMYduKYQckTm1RJoVDA557MnyUXgcuuDpry4HY/Rny9nGNcK+m3AHk94wag==
dependencies:
quill "^1.3.7"
quill-delta "^4.2.2"
"@vueuse/core@*", "@vueuse/core@^11.1.0", "@vueuse/core@11.3.0":
version "11.3.0"
resolved "https://registry.npmjs.org/@vueuse/core/-/core-11.3.0.tgz"
@ -2948,6 +2956,32 @@ cacache@^19.0.0, cacache@^19.0.1:
tar "^7.4.3"
unique-filename "^4.0.0"
call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
call-bind@^1.0.7, call-bind@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz"
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
dependencies:
call-bind-apply-helpers "^1.0.0"
es-define-property "^1.0.0"
get-intrinsic "^1.2.4"
set-function-length "^1.2.2"
call-bound@^1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz"
integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==
dependencies:
call-bind-apply-helpers "^1.0.1"
get-intrinsic "^1.2.6"
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
@ -3140,6 +3174,11 @@ clone@^1.0.2:
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
clone@^2.1.1:
version "2.1.2"
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
clone@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
@ -3566,6 +3605,18 @@ deep-eql@^5.0.1:
resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz"
integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==
deep-equal@^1.0.1:
version "1.1.2"
resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz"
integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==
dependencies:
is-arguments "^1.1.1"
is-date-object "^1.0.5"
is-regex "^1.1.4"
object-is "^1.1.5"
object-keys "^1.1.1"
regexp.prototype.flags "^1.5.1"
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz"
@ -3606,6 +3657,15 @@ defaults@^1.0.3:
dependencies:
clone "^1.0.2"
define-data-property@^1.0.1, define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"
define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz"
@ -3616,6 +3676,15 @@ define-lazy-prop@^3.0.0:
resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz"
integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==
define-properties@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz"
integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
dependencies:
define-data-property "^1.0.1"
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
defu@^6.1.2, defu@^6.1.4:
version "6.1.4"
resolved "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz"
@ -3747,6 +3816,15 @@ duck@^0.1.12:
dependencies:
underscore "^1.13.1"
dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-errors "^1.3.0"
gopd "^1.2.0"
duplexer@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz"
@ -3916,11 +3994,28 @@ errx@^0.1.0:
resolved "https://registry.npmjs.org/errx/-/errx-0.1.0.tgz"
integrity sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==
es-define-property@^1.0.0, es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-module-lexer@^1.2.1, es-module-lexer@^1.5.4, es-module-lexer@^1.6.0:
version "1.6.0"
resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz"
integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==
es-object-atoms@^1.0.0:
version "1.1.1"
resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
dependencies:
es-errors "^1.3.0"
esbuild@^0.21.3:
version "0.21.5"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz"
@ -4162,6 +4257,11 @@ event-target-shim@^5.0.0:
resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
eventemitter3@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz"
integrity sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==
events@^3.2.0, events@^3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
@ -4215,6 +4315,11 @@ export-from-json@^1.7.4:
resolved "https://registry.npmjs.org/export-from-json/-/export-from-json-1.7.4.tgz"
integrity sha512-FjmpluvZS2PTYyhkoMfQoyEJMfe2bfAyNpa5Apa6C9n7SWUWyJkG/VFnzERuj3q9Jjo3iwBjwVsDQ7Z7sczthA==
extend@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
external-editor@^3.0.3:
version "3.1.0"
resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz"
@ -4244,6 +4349,16 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-diff@1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz"
integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==
fast-diff@1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz"
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
fast-fifo@^1.2.0, fast-fifo@^1.3.2:
version "1.3.2"
resolved "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz"
@ -4471,6 +4586,11 @@ function-bind@^1.1.2:
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
functions-have-names@^1.2.3:
version "1.2.3"
resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
fuse.js@^7, fuse.js@^7.0.0:
version "7.1.0"
resolved "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz"
@ -4501,11 +4621,35 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5:
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.2.4, get-intrinsic@^1.2.6:
version "1.2.7"
resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz"
integrity sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.0.0"
function-bind "^1.1.2"
get-proto "^1.0.0"
gopd "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
math-intrinsics "^1.1.0"
get-port-please@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/get-port-please/-/get-port-please-3.1.2.tgz"
integrity sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==
get-proto@^1.0.0, get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
dependencies:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
get-stream@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz"
@ -4639,6 +4783,11 @@ globby@^14.0.2:
slash "^5.1.0"
unicorn-magic "^0.1.0"
gopd@^1.0.1, gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz"
@ -4681,6 +4830,25 @@ has-flag@^4.0.0:
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"
has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
has-tostringtag@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
has-unicode@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz"
@ -4994,6 +5162,14 @@ iron-webcrypto@^1.2.1:
resolved "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz"
integrity sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==
is-arguments@^1.1.1:
version "1.2.0"
resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz"
integrity sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==
dependencies:
call-bound "^1.0.2"
has-tostringtag "^1.0.2"
is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz"
@ -5018,6 +5194,14 @@ is-core-module@^2.13.0:
dependencies:
hasown "^2.0.2"
is-date-object@^1.0.5:
version "1.1.0"
resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz"
integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==
dependencies:
call-bound "^1.0.2"
has-tostringtag "^1.0.2"
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
@ -5092,6 +5276,16 @@ is-reference@1.2.1:
dependencies:
"@types/estree" "*"
is-regex@^1.1.4:
version "1.2.1"
resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz"
integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==
dependencies:
call-bound "^1.0.2"
gopd "^1.2.0"
has-tostringtag "^1.0.2"
hasown "^2.0.2"
is-ssh@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz"
@ -5552,6 +5746,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz"
@ -5705,6 +5904,11 @@ mammoth@^1.8.0:
underscore "^1.13.1"
xmlbuilder "^10.0.0"
math-intrinsics@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
mdn-data@2.0.28:
version "2.0.28"
resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz"
@ -6489,6 +6693,19 @@ object-assign@^4.0.1, object-assign@^4.1.1:
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-is@^1.1.5:
version "1.1.6"
resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz"
integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
ofetch@^1.3.3, ofetch@^1.4.1:
version "1.4.1"
resolved "https://registry.npmjs.org/ofetch/-/ofetch-1.4.1.tgz"
@ -6681,6 +6898,11 @@ pako@~1.0.2:
resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
parchment@^1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz"
integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
@ -7259,6 +7481,36 @@ queue-tick@^1.0.1:
resolved "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz"
integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==
quill-delta@^3.6.2:
version "3.6.3"
resolved "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz"
integrity sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==
dependencies:
deep-equal "^1.0.1"
extend "^3.0.2"
fast-diff "1.1.2"
quill-delta@^4.2.2:
version "4.2.2"
resolved "https://registry.npmjs.org/quill-delta/-/quill-delta-4.2.2.tgz"
integrity sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==
dependencies:
fast-diff "1.2.0"
lodash.clonedeep "^4.5.0"
lodash.isequal "^4.5.0"
quill@^1.3.7:
version "1.3.7"
resolved "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz"
integrity sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==
dependencies:
clone "^2.1.1"
deep-equal "^1.0.1"
eventemitter3 "^2.0.3"
extend "^3.0.2"
parchment "^1.1.4"
quill-delta "^3.6.2"
radix-vue@^1.4.9:
version "1.9.13"
resolved "https://registry.npmjs.org/radix-vue/-/radix-vue-1.9.13.tgz"
@ -7442,6 +7694,18 @@ regexp-tree@^0.1.27:
resolved "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz"
integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==
regexp.prototype.flags@^1.5.1:
version "1.5.4"
resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz"
integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==
dependencies:
call-bind "^1.0.8"
define-properties "^1.2.1"
es-errors "^1.3.0"
get-proto "^1.0.1"
gopd "^1.2.0"
set-function-name "^2.0.2"
reka-ui@1.0.0-alpha.8:
version "1.0.0-alpha.8"
resolved "https://registry.npmjs.org/reka-ui/-/reka-ui-1.0.0-alpha.8.tgz"
@ -7734,6 +7998,28 @@ set-blocking@^2.0.0:
resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
set-function-length@^1.2.2:
version "1.2.2"
resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
set-function-name@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz"
integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
functions-have-names "^1.2.3"
has-property-descriptors "^1.0.2"
setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"