WIP: add basic features
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
color="primary",
|
color="primary",
|
||||||
dense,
|
dense,
|
||||||
padding="4px 22px",
|
padding="4px 22px",
|
||||||
|
@click="openForm"
|
||||||
)
|
)
|
||||||
q-icon(
|
q-icon(
|
||||||
name="app:icon-plus",
|
name="app:icon-plus",
|
||||||
@@ -19,14 +20,11 @@
|
|||||||
size="18px",
|
size="18px",
|
||||||
style="margin-left: 4px"
|
style="margin-left: 4px"
|
||||||
)
|
)
|
||||||
q-menu(
|
base-client-form-create(
|
||||||
v-model="isOpenFormInternal",
|
v-model="isOpenFormInternal",
|
||||||
)
|
:set-updated-clients="setUpdatedClients",
|
||||||
base-client-form-create(
|
:write-created-client-id="writeCreatedClientId",
|
||||||
v-model="isOpenFormInternal",
|
)
|
||||||
:set-updated-clients="setUpdatedClients",
|
|
||||||
:write-created-client-id="writeCreatedClientId",
|
|
||||||
)
|
|
||||||
q-btn.mr-8(
|
q-btn.mr-8(
|
||||||
flat,
|
flat,
|
||||||
dense,
|
dense,
|
||||||
|
|||||||
@@ -1,99 +1,98 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
.wrapper-create.flex.flex-col.fixed.right-6.bottom-6.px-8.py-7.gap-y-8
|
base-modal(v-model="value", hide-overlay, title="Создание клиента", draggable )
|
||||||
.icon-cancel.close.absolute.top-5.right-5.cursor-pointer(@click="closeForm")
|
.wrapper-create.gap-y-8.flex.flex-col.pt-8
|
||||||
span.title.text-xl.font-bold Создание клиента
|
.flex.gap-x-4.h-fit
|
||||||
.flex.gap-x-4.h-fit
|
.flex.gap-x-3.w-full
|
||||||
.flex.gap-x-3.w-full
|
q-btn(
|
||||||
q-btn(
|
color="secondary",
|
||||||
color="secondary",
|
text-color="primary",
|
||||||
text-color="primary",
|
style="width: 40px; height: 40px",
|
||||||
style="width: 40px; height: 40px",
|
rounded
|
||||||
rounded
|
no-caps
|
||||||
no-caps
|
padding="0 16px"
|
||||||
padding="0 16px"
|
|
||||||
)
|
|
||||||
q-icon(
|
|
||||||
v-if="image === defaultIcon"
|
|
||||||
name="app:icon-download",
|
|
||||||
)
|
)
|
||||||
q-avatar(
|
q-icon(
|
||||||
v-else,
|
v-if="image === defaultIcon"
|
||||||
size="40px",
|
name="app:icon-download",
|
||||||
round
|
|
||||||
)
|
|
||||||
img(:src="image")
|
|
||||||
q-menu(
|
|
||||||
anchor="bottom middle",
|
|
||||||
self="top right",
|
|
||||||
v-model="showPopup"
|
|
||||||
)
|
|
||||||
.flex.flex-col.p-4.gap-y-3
|
|
||||||
.flex.items-center.gap-x-2.cursor-pointer(@click="changeOpenModal")
|
|
||||||
q-icon(
|
|
||||||
name="app:computer",
|
|
||||||
size="18px",
|
|
||||||
color="primary"
|
|
||||||
)
|
|
||||||
span.text-smm.title Загрузить с компьютера
|
|
||||||
.flex.items-center.gap-x-2.cursor-pointer
|
|
||||||
q-icon(
|
|
||||||
name="app:camera",
|
|
||||||
size="18px",
|
|
||||||
color="primary"
|
|
||||||
)
|
|
||||||
span.text-smm.title Сделать фото
|
|
||||||
base-modal(v-model="showModal", title="Загрузить изображение")
|
|
||||||
.flex.flex-col.items-center.justify-center(
|
|
||||||
:style="{padding: '153px 370px'}"
|
|
||||||
)
|
)
|
||||||
.avatar-wrapper.flex.relative
|
q-avatar(
|
||||||
base-input(
|
v-else,
|
||||||
circle,
|
size="40px",
|
||||||
type="file",
|
round
|
||||||
id="image-upload",
|
)
|
||||||
accept="image/*",
|
img(:src="image")
|
||||||
@change="(e) => previewImage(e)"
|
q-menu(
|
||||||
)
|
anchor="bottom middle",
|
||||||
.avatar.flex.absolute.items-center.gap-x-6
|
self="top right",
|
||||||
img.avatar.object-cover(for="image-upload", :src="image", v-if="image")
|
v-model="showPopup"
|
||||||
q-btn(
|
)
|
||||||
round,
|
.flex.flex-col.p-4.gap-y-3
|
||||||
color="primary",
|
.flex.items-center.gap-x-2.cursor-pointer(@click="changeOpenModal")
|
||||||
@click="closeAddImage",
|
q-icon(
|
||||||
icon="app:icon-ok"
|
name="app:computer",
|
||||||
|
size="18px",
|
||||||
|
color="primary"
|
||||||
)
|
)
|
||||||
base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО*", outlined)
|
span.text-smm.title Загрузить с компьютера
|
||||||
.flex.flex-col.flex-auto.l.gap-y-8
|
.flex.items-center.gap-x-2.cursor-pointer
|
||||||
.flex
|
q-icon(
|
||||||
button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(
|
name="app:camera",
|
||||||
v-for="form in forms",
|
size="18px",
|
||||||
@click="selectForm(form.component)",
|
color="primary"
|
||||||
:class="{active: form.component === currentForm}",
|
)
|
||||||
:key="form.id",
|
span.text-smm.title Сделать фото
|
||||||
:id="form.id"
|
base-modal(v-model="showModal", title="Загрузить изображение")
|
||||||
) {{form.title}}
|
.flex.flex-col.items-center.justify-center(
|
||||||
component(
|
:style="{padding: '153px 370px'}"
|
||||||
v-bind:is="currentForm",
|
)
|
||||||
:basic-info="infoClient.basic",
|
.avatar-wrapper.flex.relative
|
||||||
:phone="infoClient.phone",
|
base-input(
|
||||||
:email="infoClient.email",
|
circle,
|
||||||
:save-network-id="saveNetworkId",
|
type="file",
|
||||||
:add-network="addNewNetwork",
|
id="image-upload",
|
||||||
:choose-option="chooseOptionNetworks",
|
accept="image/*",
|
||||||
:choose-priority="choosePriority",
|
@change="(e) => previewImage(e)"
|
||||||
:priority-list="priorityList",
|
)
|
||||||
:identity-document="infoClient.identity_document",
|
.avatar.flex.absolute.items-center.gap-x-6
|
||||||
:addresses="infoClient.addresses",
|
img.avatar.object-cover(for="image-upload", :src="image", v-if="image")
|
||||||
:save-file="saveDocFile",
|
q-btn(
|
||||||
)
|
round,
|
||||||
q-btn(
|
color="primary",
|
||||||
label="Создать клиента",
|
@click="closeAddImage",
|
||||||
color="primary",
|
icon="app:icon-ok"
|
||||||
style="height: 40px; width: 180px",
|
)
|
||||||
no-caps,
|
base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО*", outlined)
|
||||||
padding="8px 24px",
|
.flex.flex-col.flex-auto.l.gap-y-8
|
||||||
@click="saveClient",
|
.flex
|
||||||
)
|
button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(
|
||||||
|
v-for="form in forms",
|
||||||
|
@click="selectForm(form.component)",
|
||||||
|
:class="{active: form.component === currentForm}",
|
||||||
|
:key="form.id",
|
||||||
|
:id="form.id"
|
||||||
|
) {{form.title}}
|
||||||
|
component(
|
||||||
|
v-bind:is="currentForm",
|
||||||
|
:basic-info="infoClient.basic",
|
||||||
|
:phone="infoClient.phone",
|
||||||
|
:email="infoClient.email",
|
||||||
|
:save-network-id="saveNetworkId",
|
||||||
|
:add-network="addNewNetwork",
|
||||||
|
:choose-option="chooseOptionNetworks",
|
||||||
|
:choose-priority="choosePriority",
|
||||||
|
:priority-list="priorityList",
|
||||||
|
:identity-document="infoClient.identity_document",
|
||||||
|
:addresses="infoClient.addresses",
|
||||||
|
:save-file="saveDocFile",
|
||||||
|
)
|
||||||
|
q-btn(
|
||||||
|
label="Создать клиента",
|
||||||
|
color="primary",
|
||||||
|
style="height: 40px; width: 180px",
|
||||||
|
no-caps,
|
||||||
|
padding="8px 24px",
|
||||||
|
@click="saveClient",
|
||||||
|
)
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -109,6 +108,7 @@ import addImageIcon from "@/assets/icons/photo.svg";
|
|||||||
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
|
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
|
||||||
import { addNotification } from "@/components/Notifications/notificationContext";
|
import { addNotification } from "@/components/Notifications/notificationContext";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
|
import { v_model } from "@/shared/mixins/v-model";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "BaseClientFormClient",
|
name: "BaseClientFormClient",
|
||||||
@@ -122,12 +122,11 @@ export default {
|
|||||||
addImageIcon,
|
addImageIcon,
|
||||||
TheNotificationProvider,
|
TheNotificationProvider,
|
||||||
},
|
},
|
||||||
emits: ["update:model-value"],
|
|
||||||
props: {
|
props: {
|
||||||
setUpdatedClients: Function,
|
setUpdatedClients: Function,
|
||||||
writeCreatedClientId: Function,
|
writeCreatedClientId: Function,
|
||||||
modelValue: Boolean,
|
|
||||||
},
|
},
|
||||||
|
mixins: [v_model],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
networksSettings: column.find((el) => el.name === "networks"),
|
networksSettings: column.find((el) => el.name === "networks"),
|
||||||
@@ -243,9 +242,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeForm() {
|
|
||||||
this.$emit("update:model-value", false);
|
|
||||||
},
|
|
||||||
previewImage(event) {
|
previewImage(event) {
|
||||||
let picture = event.target.files;
|
let picture = event.target.files;
|
||||||
let reader = new FileReader();
|
let reader = new FileReader();
|
||||||
@@ -480,12 +476,7 @@ export default {
|
|||||||
|
|
||||||
<style lang="sass" scoped>
|
<style lang="sass" scoped>
|
||||||
.wrapper-create
|
.wrapper-create
|
||||||
z-index: 5
|
width: 570px
|
||||||
background-color: var(--default-white)
|
|
||||||
border-radius: 4px
|
|
||||||
width: 634px
|
|
||||||
min-height: 585px
|
|
||||||
box-shadow: var(--default-shadow)
|
|
||||||
|
|
||||||
.title
|
.title
|
||||||
color: var(--font-dark-blue-color)
|
color: var(--font-dark-blue-color)
|
||||||
|
|||||||
@@ -1,30 +1,110 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
q-dialog(v-model="value")
|
q-dialog(
|
||||||
.base-content
|
v-model="value"
|
||||||
.base-header
|
@show="onShow",
|
||||||
|
@hide="onHide",
|
||||||
|
ref="dialog"
|
||||||
|
)
|
||||||
|
.base-content(ref="contentRef", :style="contentStyles")
|
||||||
|
q-resize-observer(@resize="onResize")
|
||||||
|
.base-header(draggable, :class="{'cursor-move': draggable}", ref="headerRef")
|
||||||
.header-title.text {{ title }}
|
.header-title.text {{ title }}
|
||||||
.icon-cancel.text-sm(@click="value = false", v-if="!showIcon")
|
.icon-cancel.text-sm(@click="value = false", v-if="!showCloseIcon")
|
||||||
slot
|
slot
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { v_model } from "@/shared/mixins/v-model";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "BaseModal",
|
name: "BaseModal",
|
||||||
|
mixins: [v_model],
|
||||||
|
emits: ["show", "hide"],
|
||||||
props: {
|
props: {
|
||||||
title: String,
|
title: String,
|
||||||
modelValue: Boolean,
|
showCloseIcon: Boolean,
|
||||||
showIcon: Boolean,
|
draggable: Boolean,
|
||||||
|
hideOverlay: Boolean,
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
data() {
|
||||||
computed: {
|
return {
|
||||||
value: {
|
contentStyles: {
|
||||||
get() {
|
top: 0,
|
||||||
return this.modelValue;
|
left: 0,
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
this.$emit("update:modelValue", value);
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onShow() {
|
||||||
|
if (this.draggable) {
|
||||||
|
this.$refs.headerRef.addEventListener("mousedown", this.onGrab);
|
||||||
|
}
|
||||||
|
this.$emit("show");
|
||||||
},
|
},
|
||||||
|
onHide() {
|
||||||
|
if (this.draggable) {
|
||||||
|
document.removeEventListener("mousemove", this.onDrag);
|
||||||
|
document.removeEventListener("mouseup", this.onLetGo);
|
||||||
|
}
|
||||||
|
this.$emit("hide");
|
||||||
|
},
|
||||||
|
onDrag(e) {
|
||||||
|
const target = this.$refs.contentRef;
|
||||||
|
const originalStyles = window.getComputedStyle(target);
|
||||||
|
const { x, width, y, height } = target.getBoundingClientRect();
|
||||||
|
if (
|
||||||
|
x + e.movementX > 10 &&
|
||||||
|
x + e.movementX + width + 10 <= window.innerWidth
|
||||||
|
)
|
||||||
|
this.contentStyles.left =
|
||||||
|
parseInt(originalStyles.left) + e.movementX + "px";
|
||||||
|
if (
|
||||||
|
y + e.movementY > 10 &&
|
||||||
|
y + e.movementY + height + 10 <= window.innerHeight
|
||||||
|
)
|
||||||
|
this.contentStyles.top =
|
||||||
|
parseInt(originalStyles.top) + e.movementY + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
onLetGo() {
|
||||||
|
document.removeEventListener("mousemove", this.onDrag);
|
||||||
|
document.removeEventListener("mouseup", this.onLetGo);
|
||||||
|
},
|
||||||
|
|
||||||
|
onGrab() {
|
||||||
|
document.addEventListener("mousemove", this.onDrag);
|
||||||
|
document.addEventListener("mouseup", this.onLetGo);
|
||||||
|
},
|
||||||
|
onResize() {
|
||||||
|
const target = this.$refs.contentRef;
|
||||||
|
const originalStyles = window.getComputedStyle(target);
|
||||||
|
const { x, width, y, height } = target.getBoundingClientRect();
|
||||||
|
if (x < 10) {
|
||||||
|
const delta = 10 - x;
|
||||||
|
this.contentStyles.left = parseInt(originalStyles.left) + delta + "px";
|
||||||
|
}
|
||||||
|
if (y < 10) {
|
||||||
|
const delta = 10 - y;
|
||||||
|
this.contentStyles.top = parseInt(originalStyles.top) + delta + "px";
|
||||||
|
}
|
||||||
|
if (x + width + 10 > window.innerWidth) {
|
||||||
|
const delta = window.innerWidth - (x + width + 10);
|
||||||
|
this.contentStyles.left = parseInt(originalStyles.left) + delta + "px";
|
||||||
|
}
|
||||||
|
if (y + height + 10 > window.innerHeight) {
|
||||||
|
const delta = window.innerHeight - (y + height + 10);
|
||||||
|
this.contentStyles.top = parseInt(originalStyles.top) + delta + "px";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
const backdropEl = this.$refs.dialog?.contentEl?.previousSibling;
|
||||||
|
if (!backdropEl) return;
|
||||||
|
if (!this.hideOverlay) {
|
||||||
|
backdropEl.style.background = "rgba(37, 40, 80, 0.2)";
|
||||||
|
backdropEl.style.backdropFilter = "blur(4px)";
|
||||||
|
} else backdropEl.style.background = "rgba(0,0,0,0)";
|
||||||
|
console.log("123");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -45,12 +125,14 @@ export default {
|
|||||||
background-color: var(--default-white)
|
background-color: var(--default-white)
|
||||||
box-shadow: 4px 4px 8px rgba(9, 10, 21, 0.1), -4px -4px 8px rgba(9, 10, 21, 0.1)
|
box-shadow: 4px 4px 8px rgba(9, 10, 21, 0.1), -4px -4px 8px rgba(9, 10, 21, 0.1)
|
||||||
border-radius: 4px
|
border-radius: 4px
|
||||||
|
position: relative
|
||||||
|
|
||||||
.header-title
|
.header-title
|
||||||
font-weight: 700
|
font-weight: 700
|
||||||
font-size: 20px
|
font-size: 20px
|
||||||
line-height: 23px
|
line-height: 23px
|
||||||
color: var(--font-dark-blue-color)
|
color: var(--font-dark-blue-color)
|
||||||
|
user-select: none
|
||||||
.base-header
|
.base-header
|
||||||
display: flex
|
display: flex
|
||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
@@ -62,10 +144,6 @@ export default {
|
|||||||
color: var(--font-grey-color)
|
color: var(--font-grey-color)
|
||||||
</style>
|
</style>
|
||||||
<style lang="sass">
|
<style lang="sass">
|
||||||
.q-dialog__backdrop
|
|
||||||
background: rgba(37, 40, 80, 0.2) !important
|
|
||||||
backdrop-filter: blur(4px) !important
|
|
||||||
|
|
||||||
@media (min-width: 600px)
|
@media (min-width: 600px)
|
||||||
.q-dialog__inner--minimized > div
|
.q-dialog__inner--minimized > div
|
||||||
max-width: 100vh !important
|
max-width: 100vh !important
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
)
|
)
|
||||||
base-modal(
|
base-modal(
|
||||||
v-model="showModal",
|
v-model="showModal",
|
||||||
:showIcon="isOpenAddDoc"
|
:showCloseIcon="isOpenAddDoc"
|
||||||
)
|
)
|
||||||
table-adding-new-doc(
|
table-adding-new-doc(
|
||||||
v-if="isOpenAddDoc",
|
v-if="isOpenAddDoc",
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
//- )
|
//- )
|
||||||
base-modal(
|
base-modal(
|
||||||
v-model="showModal",
|
v-model="showModal",
|
||||||
:title="titleModal",
|
:title="titleModal"
|
||||||
)
|
)
|
||||||
client-table-modal(
|
client-table-modal(
|
||||||
v-for="modal in modalConfig"
|
v-for="modal in modalConfig"
|
||||||
@@ -68,7 +68,6 @@ import ClientsTableHeader from "@/pages/clients/components/ClientsTableHeader";
|
|||||||
import ClientsTableHat from "@/pages/clients/components/ClientsTableHat";
|
import ClientsTableHat from "@/pages/clients/components/ClientsTableHat";
|
||||||
import ClientsTableRow from "@/pages/clients/components/ClientsTableRow";
|
import ClientsTableRow from "@/pages/clients/components/ClientsTableRow";
|
||||||
import ClientsTableCheckbox from "@/pages/clients/components/ClientsTableCheckbox";
|
import ClientsTableCheckbox from "@/pages/clients/components/ClientsTableCheckbox";
|
||||||
import BaseClientFormCreate from "@/components/base/BaseClientFormCreate";
|
|
||||||
import ClientTablePagination from "./ClientTablePagination.vue";
|
import ClientTablePagination from "./ClientTablePagination.vue";
|
||||||
import BaseModal from "@/components/base/BaseModal.vue";
|
import BaseModal from "@/components/base/BaseModal.vue";
|
||||||
import ClientTableModal from "./ClientTableModal.vue";
|
import ClientTableModal from "./ClientTableModal.vue";
|
||||||
@@ -82,7 +81,6 @@ export default {
|
|||||||
ClientsTableRow,
|
ClientsTableRow,
|
||||||
ClientsTableHat,
|
ClientsTableHat,
|
||||||
ClientsTableHeader,
|
ClientsTableHeader,
|
||||||
BaseClientFormCreate,
|
|
||||||
ClientTablePagination,
|
ClientTablePagination,
|
||||||
BaseModal,
|
BaseModal,
|
||||||
ClientTableModal,
|
ClientTableModal,
|
||||||
|
|||||||
14
src/shared/mixins/v-model.js
Normal file
14
src/shared/mixins/v-model.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export const v_model = {
|
||||||
|
props: ["modelValue"],
|
||||||
|
emits: ["update:modelValue"],
|
||||||
|
computed: {
|
||||||
|
value: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit("update:modelValue", val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user