@coopenomics/desktop 2025.5.5 → 2025.5.14-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.html +21 -2
- package/package.json +5 -5
- package/src/entities/Registrator/model/store.ts +16 -11
- package/src/entities/Wallet/api/index.ts +5 -3
- package/src/features/Agreementer/SignAgreementDialog/model/index.ts +5 -3
- package/src/features/Agreementer/SignAgreementDialog/ui/SignAgreementDialog.vue +1 -1
- package/src/features/Decision/AuthorizeAndExecDecision/model/index.ts +6 -9
- package/src/features/Decision/CreateProject/model/index.ts +1 -1
- package/src/features/Decision/VoteAgainstDecision/model/index.ts +14 -2
- package/src/features/Decision/VoteForDecision/model/index.ts +9 -5
- package/src/features/FreeDecision/CreateProject/model/index.ts +1 -1
- package/src/features/Meet/CloseMeetWithDecision/model/index.ts +13 -13
- package/src/features/Meet/CreateMeet/model/index.ts +1 -1
- package/src/features/Meet/RestartMeet/model/index.ts +6 -3
- package/src/features/Request/AcceptRequest/api/index.ts +3 -10
- package/src/features/Request/ConfirmRecieveOnRequest/api/index.ts +4 -9
- package/src/features/Request/ConfirmSupplyOnRequest/api/index.ts +6 -11
- package/src/features/Request/ConfirmSupplyOnRequest/ui/ConfirmSupplyOnRequestButton.vue +1 -1
- package/src/features/Request/CreateChildOrder/model/index.ts +35 -30
- package/src/features/Request/CreateChildOrder/ui/CreateChildOrderButton/CreateChildOrderButton.vue +20 -15
- package/src/features/Request/DisputeOnRequest/api/index.ts +19 -24
- package/src/features/Request/DisputeOnRequest/ui/DisputeOnRequestButton.vue +1 -1
- package/src/features/Request/RecieveOnRequest/api/index.ts +6 -11
- package/src/features/Request/RecieveOnRequest/ui/RecieveOnRequestButton.vue +1 -1
- package/src/features/Request/SupplyOnRequest/api/index.ts +18 -27
- package/src/features/Union/AddCooperative/ui/AddCooperativeForm.vue +7 -5
- package/src/features/User/CreateUser/api/index.ts +28 -10
- package/src/features/User/CreateUser/model/index.ts +39 -31
- package/src/pages/Cooperative/ListOfAgenda/ui/ListOfAgendaQuestions.vue +8 -8
- package/src/pages/Cooperative/ListOfParticipants/ui/ListOfParticipantsPage.vue +3 -3
- package/src/pages/Registrator/SignUp/EmailInput.vue +0 -7
- package/src/pages/Union/ConnectionAgreement/ConnectionAgreementPage.vue +1 -1
- package/src/processes/init-app/index.ts +2 -0
- package/src/processes/process-decisions/index.ts +32 -29
- package/src/processes/select-branch/index.ts +1 -1
- package/src/shared/api/indexDB.ts +0 -1
- package/src/shared/lib/document/model/const.ts +30 -0
- package/src/shared/lib/document/model/entity.ts +33 -21
- package/src/shared/lib/document/model/index.ts +1 -1
- package/src/shared/lib/document/model/types.ts +2 -3
- package/src/shared/lib/types/document/index.ts +11 -13
- package/src/shared/lib/types/user/IUserData.ts +5 -6
- package/src/shared/lib/types/user/index.ts +1 -11
- package/src/shared/lib/utils/account.ts +24 -0
- package/src/shared/lib/utils/index.ts +2 -0
- package/src/shared/lib/utils/theme.ts +30 -0
- package/src/shared/store/index.ts +9 -5
- package/src/shared/ui/BaseDocument/BaseDocument.vue +43 -42
- package/src/shared/ui/ComplexDocument/ComplexDocument.vue +7 -5
- package/src/shared/ui/ToogleDarkLight/ToogleDarkLight.vue +8 -1
- package/src/shared/ui/ZodForm/ZodForm.vue +1 -1
- package/src/widgets/Cooperative/Documents/ListOfDocuments/ui/DocumentsTable.vue +3 -2
- package/src/widgets/Cooperative/Payments/ListOfPayments/ui/ListOfPaymentsWidget.vue +9 -10
- package/src/widgets/Meets/MeetDetailsVoting/model.ts +4 -4
- package/src/widgets/Participants/ui/ParticipantCard.vue +17 -9
- package/src/widgets/Participants/ui/ParticipantDetails.vue +7 -6
- package/src/widgets/Participants/ui/ParticipantsTable.vue +29 -23
- package/src/widgets/Questions/ui/QuestionsTable/QuestionsTable.vue +8 -8
- package/src/widgets/RequireAgreements/ui/RequireAgreements.vue +1 -1
@@ -4,55 +4,56 @@ q-card(:flat="isMobile" style="word-break: break-all !important; white-space: no
|
|
4
4
|
div(v-if="loading").full-width.text-center
|
5
5
|
div(style="margin:auto;").flex.q-pa-sm.full-width.text-center
|
6
6
|
q-spinner
|
7
|
-
span.q-ml-sm.text-grey подговка {{doc
|
7
|
+
span.q-ml-sm.text-grey подговка {{doc?.meta?.title}}
|
8
8
|
div(v-if="!loading")
|
9
9
|
div(v-html="safeHtml").description.q-pa-xs
|
10
10
|
div.row.q-mt-lg.q-pa-sm.justify-center
|
11
11
|
|
12
12
|
q-card(style="word-break: break-all !important; text-wrap: pretty;" flat).col-md-8.col-xs-12.q-pa-sm.verify-card
|
13
13
|
div.q-mr-lg.q-mt-md
|
14
|
-
q-badge(:color="
|
15
|
-
q-icon(:name="
|
14
|
+
q-badge(:color="documentAggregate?.document?.doc_hash == regeneratedHash ? 'teal' : 'red'").text-center.q-pa-xs
|
15
|
+
q-icon(:name="documentAggregate?.document?.doc_hash == regeneratedHash ? 'check_circle' : 'cancel'" ).q-mr-sm
|
16
16
|
span контрольная сумма
|
17
|
-
p.q-mr-lg.q-ml-lg.text-grey {{
|
17
|
+
p.q-mr-lg.q-ml-lg.text-grey {{ documentAggregate?.document?.doc_hash }}
|
18
18
|
|
19
19
|
// Показываем все подписи (если это агрегат документа)
|
20
|
-
template(v-if="documentAggregate
|
20
|
+
template(v-if="documentAggregate?.document?.signatures && documentAggregate.document.signatures.length > 0")
|
21
21
|
div.q-mr-lg.q-mt-md
|
22
|
+
|
22
23
|
q-badge(:color="hasInvalidSignature ? 'red' : 'teal'").text-center.q-pa-xs
|
23
24
|
q-icon(:name="hasInvalidSignature ? 'cancel' : 'verified'").q-mr-sm
|
24
|
-
span Подписи ({{ documentAggregate.signatures.length }})
|
25
|
+
span Подписи ({{ documentAggregate.document.signatures.length }})
|
25
26
|
|
26
27
|
// Список всех подписей
|
27
28
|
q-list(bordered separator dense)
|
28
29
|
q-expansion-item(
|
29
|
-
v-for="(signature, index) in documentAggregate.signatures"
|
30
|
+
v-for="(signature, index) in documentAggregate.document.signatures"
|
30
31
|
:key="index"
|
31
|
-
:label="`Подпись ${index + 1}: ${getSignerName(signature.
|
32
|
+
:label="`Подпись ${index + 1}: ${getSignerName(signature.signer_info)}`"
|
32
33
|
header-class="signature-header"
|
33
34
|
dense
|
34
35
|
)
|
35
36
|
q-card(flat)
|
36
37
|
q-card-section
|
37
38
|
div.q-mb-sm
|
38
|
-
q-badge(:color="
|
39
|
+
q-badge(:color="signature.is_valid ? 'teal' : 'red'").text-center.q-pa-xs
|
39
40
|
span Подписант
|
40
|
-
p.q-mt-sm.q-ml-lg {{ getSignerName(signature.
|
41
|
+
p.q-mt-sm.q-ml-lg {{ getSignerName(signature.signer_info) }}
|
41
42
|
|
42
43
|
div(v-if="signature.public_key").q-mb-sm
|
43
|
-
q-badge(:color="
|
44
|
+
q-badge(:color="signature.is_valid ? 'teal' : 'red'").text-center.q-pa-xs
|
44
45
|
span Публичный ключ
|
45
46
|
p.q-mt-sm.q-ml-lg {{ signature.public_key }}
|
46
47
|
|
47
48
|
div(v-if="signature.signature").q-mb-sm
|
48
|
-
q-badge(:color="
|
49
|
+
q-badge(:color="signature.is_valid ? 'teal' : 'red'").text-center.q-pa-xs
|
49
50
|
span Цифровая подпись
|
50
51
|
p.q-mt-sm.q-ml-lg {{ signature.signature }}
|
51
52
|
|
52
53
|
div.q-mt-md
|
53
|
-
q-badge(:color="
|
54
|
-
q-icon(:name="
|
55
|
-
span Статус подписи: {{
|
54
|
+
q-badge(:color="signature.is_valid ? 'teal' : 'red'").text-center.q-pa-xs
|
55
|
+
q-icon(:name="signature.is_valid ? 'check_circle' : 'cancel'").q-mr-sm
|
56
|
+
span Статус подписи: {{ signature.is_valid ? 'Верифицирована' : 'Не верифицирована' }}
|
56
57
|
|
57
58
|
div.text-center.q-gutter-sm.q-mt-md
|
58
59
|
q-btn(size="sm" color="primary" icon="download" @click="download") скачать
|
@@ -63,24 +64,24 @@ q-card(:flat="isMobile" style="word-break: break-all !important; white-space: no
|
|
63
64
|
</template>
|
64
65
|
<script setup lang="ts">
|
65
66
|
import { ref, computed, onMounted } from 'vue'
|
66
|
-
import { Signature, PublicKey } from '@wharfkit/antelope';
|
67
67
|
import { useGlobalStore } from 'src/shared/store';
|
68
68
|
import DOMPurify from 'dompurify';
|
69
69
|
import { DigitalDocument } from 'src/shared/lib/document';
|
70
70
|
import { FailAlert, SuccessAlert } from 'src/shared/api';
|
71
71
|
import { getNameFromUserData } from 'src/shared/lib/utils/getNameFromUserData';
|
72
72
|
import { useWindowSize } from 'src/shared/hooks';
|
73
|
+
import type { IDocumentAggregate } from 'src/entities/Document/model';
|
73
74
|
|
74
75
|
const props = defineProps({
|
75
76
|
documentAggregate: {
|
76
|
-
type: Object,
|
77
|
+
type: Object as () => IDocumentAggregate,
|
77
78
|
required: true
|
78
79
|
}
|
79
80
|
})
|
80
81
|
|
81
82
|
const doc = computed(() => props.documentAggregate.rawDocument)
|
83
|
+
|
82
84
|
const loading = ref(false)
|
83
|
-
const signatures_verified = ref<boolean[]>([])
|
84
85
|
const { isMobile } = useWindowSize()
|
85
86
|
const regeneratedHash = ref()
|
86
87
|
const onRegenerate = ref(false)
|
@@ -90,7 +91,7 @@ const regenerate = async() => {
|
|
90
91
|
try {
|
91
92
|
onRegenerate.value = true
|
92
93
|
|
93
|
-
regenerated.value = await new DigitalDocument().generate({...doc.value
|
94
|
+
regenerated.value = await new DigitalDocument().generate({...doc.value?.meta}, {skip_save: true})
|
94
95
|
|
95
96
|
if (regenerated.value.hash == regeneratedHash.value)
|
96
97
|
SuccessAlert('Сверка прошла успешно: аналогичный документ восстановлен из исходных данных')
|
@@ -108,13 +109,13 @@ function sanitizeHtml(html: string) {
|
|
108
109
|
return DOMPurify.sanitize(html);
|
109
110
|
}
|
110
111
|
|
111
|
-
const safeHtml = computed(() => sanitizeHtml(doc.value
|
112
|
+
const safeHtml = computed(() => sanitizeHtml(doc.value?.html ?? ''));
|
112
113
|
|
113
114
|
|
114
115
|
const hashBuffer = async () => {
|
115
116
|
try {
|
116
117
|
// Декодирование из base64
|
117
|
-
const binaryString = atob(doc.value
|
118
|
+
const binaryString = atob(doc.value?.binary ?? '');
|
118
119
|
const len = binaryString.length;
|
119
120
|
const data = new Uint8Array(len);
|
120
121
|
|
@@ -138,24 +139,24 @@ const getSignerName = (signer: any) => {
|
|
138
139
|
|
139
140
|
// Верификация всех подписей из агрегата
|
140
141
|
const verifySignatures = () => {
|
141
|
-
if (props.documentAggregate?.signatures?.length > 0) {
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
}
|
142
|
+
// if (props.documentAggregate?.document?.signatures?.length > 0) {
|
143
|
+
// signatures_verified.value = props.documentAggregate.document.signatures.map(signatureData => {
|
144
|
+
// try {
|
145
|
+
// if (signatureData.public_key && signatureData.signature) {
|
146
|
+
// const public_key = PublicKey.from(signatureData.public_key)
|
147
|
+
// const signature = Signature.from(signatureData.signature)
|
148
|
+
// const hash = doc.value?.hash
|
149
|
+
// const is_valid = signature.verifyDigest(hash, public_key)
|
150
|
+
// return is_valid
|
151
|
+
// } else {
|
152
|
+
// return signatureData.is_valid
|
153
|
+
// }
|
154
|
+
// } catch (error) {
|
155
|
+
// console.error('Ошибка при верификации подписи:', error)
|
156
|
+
// return false
|
157
|
+
// }
|
158
|
+
// })
|
159
|
+
// }
|
159
160
|
}
|
160
161
|
|
161
162
|
onMounted(() => {
|
@@ -167,8 +168,8 @@ async function download() {
|
|
167
168
|
try {
|
168
169
|
// PDF теперь в формате base64, можно использовать data URL
|
169
170
|
const link = document.createElement('a');
|
170
|
-
link.href = `data:application/pdf;base64,${doc.value
|
171
|
-
link.download = doc.value
|
171
|
+
link.href = `data:application/pdf;base64,${doc.value?.binary}`;
|
172
|
+
link.download = doc.value?.full_title ? doc.value?.full_title : `${doc.value?.meta?.title} - ${doc.value?.meta?.username} - ${doc.value?.meta?.created_at}.pdf`;
|
172
173
|
|
173
174
|
document.body.appendChild(link);
|
174
175
|
link.click();
|
@@ -179,7 +180,7 @@ async function download() {
|
|
179
180
|
}
|
180
181
|
|
181
182
|
// Вычисляем, есть ли хотя бы одна невалидная подпись
|
182
|
-
const hasInvalidSignature = computed(() =>
|
183
|
+
const hasInvalidSignature = computed(() => props.documentAggregate?.document?.signatures?.some(signature => !signature.is_valid))
|
183
184
|
|
184
185
|
</script>
|
185
186
|
<style>
|
@@ -7,6 +7,12 @@
|
|
7
7
|
:documentAggregate="documentData.statement.documentAggregate"
|
8
8
|
)
|
9
9
|
|
10
|
+
// Отображение документа решения с агрегатом
|
11
|
+
BaseDocument(
|
12
|
+
v-if="documentData.decision && documentData.decision.documentAggregate"
|
13
|
+
:documentAggregate="documentData.decision.documentAggregate"
|
14
|
+
)
|
15
|
+
|
10
16
|
// Отображение связанных документов из агрегата
|
11
17
|
div(v-if="documentData.links.length > 0 && documentData.statement")
|
12
18
|
div(
|
@@ -17,11 +23,7 @@
|
|
17
23
|
:documentAggregate="linkedDoc"
|
18
24
|
)
|
19
25
|
|
20
|
-
|
21
|
-
BaseDocument(
|
22
|
-
v-if="documentData.decision && documentData.decision.documentAggregate"
|
23
|
-
:documentAggregate="documentData.decision.documentAggregate"
|
24
|
-
)
|
26
|
+
|
25
27
|
</template>
|
26
28
|
|
27
29
|
<script setup lang="ts">
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<template lang="pug">
|
2
|
-
q-item(flat clickable @click="
|
2
|
+
q-item(flat clickable @click="toggleTheme")
|
3
3
|
q-item-section
|
4
4
|
q-item-label
|
5
5
|
q-icon(:name="isDark ? 'brightness_7' : 'brightness_3'").q-mr-sm
|
@@ -11,9 +11,11 @@ q-item(flat clickable @click="$q.dark.toggle()")
|
|
11
11
|
|
12
12
|
import { useQuasar } from 'quasar';
|
13
13
|
import { computed } from 'vue';
|
14
|
+
import { saveThemeToStorage } from 'src/shared/lib/utils';
|
14
15
|
|
15
16
|
const $q = useQuasar()
|
16
17
|
const isDark = computed(() => $q.dark.isActive)
|
18
|
+
|
17
19
|
defineProps({
|
18
20
|
isMobile: {
|
19
21
|
type: Boolean,
|
@@ -26,6 +28,11 @@ defineProps({
|
|
26
28
|
required: false
|
27
29
|
}
|
28
30
|
})
|
31
|
+
|
32
|
+
function toggleTheme() {
|
33
|
+
$q.dark.toggle();
|
34
|
+
saveThemeToStorage($q.dark.isActive);
|
35
|
+
}
|
29
36
|
</script>
|
30
37
|
<style scoped>
|
31
38
|
.btn-font {
|
@@ -18,7 +18,7 @@ div
|
|
18
18
|
</template>
|
19
19
|
<script lang="ts" setup>
|
20
20
|
import { defineProps, defineEmits, reactive, watch } from 'vue';
|
21
|
-
import { QInput, QCheckbox, QSelect
|
21
|
+
import { QInput, QCheckbox, QSelect } from 'quasar';
|
22
22
|
import type { IExtensionConfigSchema, ISchemaProperty } from 'src/entities/Extension/model';
|
23
23
|
|
24
24
|
// Устанавливаем имя компонента для рекурсивного вызова
|
@@ -51,8 +51,9 @@ div.scroll-area(style="height: 90vh; overflow-y: auto;")
|
|
51
51
|
|
52
52
|
q-td {{ getDocumentHash(props.row).substring(0, 10) || '' }}
|
53
53
|
q-td {{ getDocumentTitle(props.row) }}
|
54
|
-
|
54
|
+
|
55
55
|
q-tr(
|
56
|
+
no-hover
|
56
57
|
v-if="expanded.get(props.row?.id || props.row?.statement?.action?.global_sequence)"
|
57
58
|
:key="`e_${props.row?.id || props.row?.statement?.action?.global_sequence}`"
|
58
59
|
:props="props"
|
@@ -145,7 +146,7 @@ const columns:any[] = [
|
|
145
146
|
field: (row: any) => getDocumentTitle(row),
|
146
147
|
sortable: true
|
147
148
|
},
|
148
|
-
|
149
|
+
|
149
150
|
]
|
150
151
|
|
151
152
|
// Функция для переключения состояния развертывания
|
@@ -29,7 +29,6 @@
|
|
29
29
|
:hideActions="hideActions"
|
30
30
|
@toggle-expand="toggleExpand(props.row.id)"
|
31
31
|
)
|
32
|
-
|
33
32
|
template(#header="props")
|
34
33
|
q-tr(:props="props")
|
35
34
|
q-th(auto-width)
|
@@ -51,14 +50,12 @@
|
|
51
50
|
:icon="expanded.get(props.row.id) ? 'remove' : 'add'"
|
52
51
|
@click="toggleExpand(props.row.id)"
|
53
52
|
)
|
54
|
-
q-td {{props.row.
|
55
|
-
q-td {{ props.row.amount }}
|
56
|
-
q-td
|
57
|
-
q-badge(v-if="props.row.type === 'registration'" color="teal") регистрационный
|
58
|
-
q-badge(v-else color="teal") паевой
|
59
|
-
|
60
|
-
q-td(style="max-width: 150px; word-wrap: break-word; white-space: normal;") {{props.row.username}}
|
53
|
+
q-td(style="max-width: 150px; word-wrap: break-word; white-space: normal;") {{ getName(props.row.account) }}
|
61
54
|
|
55
|
+
q-td {{ props.row.amount }} {{props.row.symbol}}
|
56
|
+
q-td
|
57
|
+
span(v-if="props.row.type === 'registration'") регистрационный
|
58
|
+
span(v-else) паевой
|
62
59
|
|
63
60
|
q-td
|
64
61
|
q-badge(v-if="props.row.status ==='COMPLETED'" color="teal") обработан
|
@@ -88,6 +85,7 @@
|
|
88
85
|
import { SetOrderPaidStatusButton } from 'src/features/Payment/SetStatus/ui/SetOrderPaidStatusButton';
|
89
86
|
import PaymentCard from './PaymentCard.vue';
|
90
87
|
import { useWindowSize } from 'src/shared/hooks';
|
88
|
+
import { getName } from 'src/shared/lib/utils';
|
91
89
|
|
92
90
|
const paymentStore = usePaymentStore()
|
93
91
|
const payments = computed(() => paymentStore.payments)
|
@@ -190,10 +188,11 @@
|
|
190
188
|
|
191
189
|
|
192
190
|
const columns: any[] = [
|
193
|
-
{ name: 'id', align: 'left', label: '№', field: 'id', sortable: true },
|
191
|
+
// { name: 'id', align: 'left', label: '№', field: 'id', sortable: true },
|
192
|
+
{ name: 'account', align: 'left', label: 'От кого', field: 'account', sortable: true },
|
194
193
|
{ name: 'amount', align: 'left', label: 'Сумма', field: 'amount', sortable: true },
|
195
194
|
{ name: 'type', align: 'left', label: 'Тип платежа', field: '', sortable: false },
|
196
|
-
{ name: 'username', align: 'left', label: '
|
195
|
+
// { name: 'username', align: 'left', label: 'Аккаунт', field: 'username', sortable: true },
|
197
196
|
{ name: 'status', align: 'left', label: 'Статус', field: 'status', sortable: true },
|
198
197
|
{ name: 'actions', align: 'left', label: '', field: '', sortable: false, hide: props.hideActions },
|
199
198
|
] as any
|
@@ -30,11 +30,11 @@ export const useMeetDetailsVoting = (
|
|
30
30
|
if (!meet?.processing?.meet) return false
|
31
31
|
|
32
32
|
const isAuthorized = meet.processing.meet.status === 'authorized'
|
33
|
-
|
33
|
+
|
34
34
|
const now = moment()
|
35
35
|
const openAt = moment(meet.processing.meet.open_at)
|
36
36
|
const closeAt = moment(meet.processing.meet.close_at)
|
37
|
-
|
37
|
+
|
38
38
|
const isWithinTimeframe = now.isAfter(openAt) && now.isBefore(closeAt)
|
39
39
|
|
40
40
|
return isAuthorized && isWithinTimeframe
|
@@ -84,7 +84,7 @@ export const useMeetDetailsVoting = (
|
|
84
84
|
username: sessionStore.username,
|
85
85
|
})
|
86
86
|
|
87
|
-
const signedBallot = await signDocument(generatedBallot)
|
87
|
+
const signedBallot = await signDocument(generatedBallot, sessionStore.username)
|
88
88
|
|
89
89
|
const vote: IVoteOnMeetInput = {
|
90
90
|
coopname,
|
@@ -114,4 +114,4 @@ export const useMeetDetailsVoting = (
|
|
114
114
|
formattedCloseDate,
|
115
115
|
submitVote
|
116
116
|
}
|
117
|
-
}
|
117
|
+
}
|
@@ -5,12 +5,20 @@ div.q-pa-xs.col-xs-12.col-sm-6.col-md-4.col-lg-3.q-mt-md
|
|
5
5
|
div.text-h6 {{ getName(participant) }}
|
6
6
|
q-separator.q-my-md
|
7
7
|
div
|
8
|
-
div.
|
9
|
-
|
10
|
-
|
11
|
-
div.
|
12
|
-
|
13
|
-
|
8
|
+
div.q-mb-md
|
9
|
+
div.text-caption Аккаунт:
|
10
|
+
div.text-subtitle1.q-mb-xs {{ participant.username }}
|
11
|
+
div.q-mb-md
|
12
|
+
div.text-caption Дата вступления:
|
13
|
+
div.text-subtitle1.q-mb-xs {{ formatDate(String(participant.participant_account?.created_at || '')) == '' ? 'отсутствует' : formatDate(String(participant.participant_account?.created_at || '')) }}
|
14
|
+
div
|
15
|
+
div.text-caption Активен:
|
16
|
+
q-checkbox(
|
17
|
+
:model-value="participant.participant_account?.status === 'accepted'"
|
18
|
+
disable
|
19
|
+
color="primary"
|
20
|
+
size="sm"
|
21
|
+
)
|
14
22
|
q-card-actions(align="right")
|
15
23
|
q-btn(
|
16
24
|
color="primary"
|
@@ -63,11 +71,11 @@ const getName = (account: IAccount) => {
|
|
63
71
|
const d = account.private_account
|
64
72
|
if (!d) return ''
|
65
73
|
switch (d.type) {
|
66
|
-
case AccountTypes.
|
74
|
+
case AccountTypes.individual:
|
67
75
|
return `${d.individual_data?.last_name} ${d.individual_data?.first_name} ${d.individual_data?.middle_name}`
|
68
|
-
case AccountTypes.
|
76
|
+
case AccountTypes.entrepreneur:
|
69
77
|
return `ИП ${d.entrepreneur_data?.last_name} ${d.entrepreneur_data?.first_name} ${d.entrepreneur_data?.middle_name}`
|
70
|
-
case AccountTypes.
|
78
|
+
case AccountTypes.organization:
|
71
79
|
return d.organization_data?.short_name
|
72
80
|
default:
|
73
81
|
return ''
|
@@ -12,6 +12,7 @@ div
|
|
12
12
|
|
13
13
|
q-tab-panels.q-mt-sm.tab-panels-card(v-model="currentTab" animated)
|
14
14
|
q-tab-panel.q-pa-none(name="info")
|
15
|
+
//приватные данные
|
15
16
|
component(:is="useComponent(participant)" :participantData="usePrivateData(participant)" @update="onUpdate")
|
16
17
|
|
17
18
|
q-tab-panel.q-pa-none(name="document")
|
@@ -57,18 +58,18 @@ watch(() => props.tabName, (newVal) => {
|
|
57
58
|
// Компонент для редактирования данных
|
58
59
|
const useComponent = (account: IAccount) => {
|
59
60
|
switch (account.private_account?.type) {
|
60
|
-
case AccountTypes.
|
61
|
-
case AccountTypes.
|
62
|
-
case AccountTypes.
|
61
|
+
case AccountTypes.individual: return EditableIndividualCard
|
62
|
+
case AccountTypes.entrepreneur: return EditableEntrepreneurCard
|
63
|
+
case AccountTypes.organization: return EditableOrganizationCard
|
63
64
|
}
|
64
65
|
}
|
65
66
|
|
66
67
|
// Получение данных участника
|
67
68
|
const usePrivateData = (account: IAccount) => {
|
68
69
|
switch (account.private_account?.type) {
|
69
|
-
case AccountTypes.
|
70
|
-
case AccountTypes.
|
71
|
-
case AccountTypes.
|
70
|
+
case AccountTypes.individual: return account.private_account.individual_data
|
71
|
+
case AccountTypes.entrepreneur: return account.private_account.entrepreneur_data
|
72
|
+
case AccountTypes.organization: return account.private_account.organization_data
|
72
73
|
}
|
73
74
|
}
|
74
75
|
|
@@ -31,17 +31,28 @@ q-table(
|
|
31
31
|
:icon="expanded.get(props.row.username) ? 'remove' : 'add'"
|
32
32
|
@click="onToggleExpand(props.row.username)"
|
33
33
|
)
|
34
|
+
|
34
35
|
q-td(style="max-width: 150px; word-wrap: break-word; white-space: normal;") {{ getName(props.row) }}
|
35
|
-
q-td {{ props.row.provider_account?.email }}
|
36
36
|
q-td {{ props.row.username }}
|
37
|
-
|
37
|
+
|
38
|
+
q-td {{ formatDate(props.row.participant_account?.created_at) == '' ? 'отсутствует' : formatDate(props.row.participant_account?.created_at) }}
|
39
|
+
|
40
|
+
q-td
|
41
|
+
q-checkbox(
|
42
|
+
:model-value="props.row.participant_account?.status === 'accepted'"
|
43
|
+
disable
|
44
|
+
color="primary"
|
45
|
+
size="sm"
|
46
|
+
)
|
47
|
+
|
38
48
|
q-tr(
|
49
|
+
no-hover
|
39
50
|
v-if="expanded.get(props.row.username)"
|
40
51
|
:key="`e_${props.row.username}`"
|
41
52
|
:props="props"
|
42
53
|
class="q-virtual-scroll--with-prev"
|
43
|
-
)
|
44
|
-
q-td(colspan="100%")
|
54
|
+
).no-hover
|
55
|
+
q-td(colspan="100%").no-hover
|
45
56
|
ParticipantDetails(
|
46
57
|
:participant="props.row"
|
47
58
|
:tab-name="currentTab[props.row.username]"
|
@@ -62,8 +73,8 @@ import { ref, reactive } from 'vue'
|
|
62
73
|
import { useWindowSize } from 'src/shared/hooks'
|
63
74
|
import moment from 'moment-with-locales-es6'
|
64
75
|
import { ParticipantCard, ParticipantDetails } from '.'
|
76
|
+
import { getName } from 'src/shared/lib/utils'
|
65
77
|
import {
|
66
|
-
AccountTypes,
|
67
78
|
type IAccount,
|
68
79
|
type IIndividualData,
|
69
80
|
type IOrganizationData,
|
@@ -91,27 +102,11 @@ const { isMobile } = useWindowSize()
|
|
91
102
|
// Колонки таблицы
|
92
103
|
const columns: any[] = [
|
93
104
|
{ name: 'name', align: 'left', label: 'ФИО / Наименование', field: 'name', sortable: true },
|
94
|
-
{ name: 'email', align: 'left', label: 'Е-почта', field: 'email', sortable: true },
|
95
105
|
{ name: 'username', align: 'left', label: 'Аккаунт', field: 'username', sortable: true },
|
96
|
-
{ name: 'created_at', align: 'left', label: '
|
106
|
+
{ name: 'created_at', align: 'left', label: 'Дата вступления', field: 'created_at', sortable: true },
|
107
|
+
{ name: 'status', align: 'left', label: 'Активен', field: 'status', sortable: true },
|
97
108
|
]
|
98
109
|
|
99
|
-
// Функция для получения имени участника
|
100
|
-
const getName = (account: IAccount) => {
|
101
|
-
const d = account.private_account
|
102
|
-
if (!d) return ''
|
103
|
-
switch (d.type) {
|
104
|
-
case AccountTypes.Individual:
|
105
|
-
return `${d.individual_data?.last_name} ${d.individual_data?.first_name} ${d.individual_data?.middle_name}`
|
106
|
-
case AccountTypes.Entrepreneur:
|
107
|
-
return `ИП ${d.entrepreneur_data?.last_name} ${d.entrepreneur_data?.first_name} ${d.entrepreneur_data?.middle_name}`
|
108
|
-
case AccountTypes.Organization:
|
109
|
-
return d.organization_data?.short_name
|
110
|
-
default:
|
111
|
-
return ''
|
112
|
-
}
|
113
|
-
}
|
114
|
-
|
115
110
|
// Форматирование даты
|
116
111
|
const formatDate = (date?: string) =>
|
117
112
|
date ? moment(date).format('DD.MM.YY HH:mm:ss') : ''
|
@@ -127,3 +122,14 @@ const onUpdate = (account: IAccount, newData: IIndividualData | IOrganizationDat
|
|
127
122
|
emit('update', account, newData)
|
128
123
|
}
|
129
124
|
</script>
|
125
|
+
|
126
|
+
<style>
|
127
|
+
.no-hover.q-tr--hover,
|
128
|
+
.no-hover.q-table__tr--hover,
|
129
|
+
.no-hover:hover,
|
130
|
+
.no-hover:focus {
|
131
|
+
background: transparent !important;
|
132
|
+
box-shadow: none !important;
|
133
|
+
cursor: default !important;
|
134
|
+
}
|
135
|
+
</style>
|
@@ -30,8 +30,8 @@ div.scroll-area(style="height: 90vh; overflow-y: auto;")
|
|
30
30
|
:is-voted-any="isVotedAny"
|
31
31
|
@toggle-expand="toggleExpand(props.row.table.id)"
|
32
32
|
@authorize="onAuthorizeDecision(props.row)"
|
33
|
-
@vote-for="onVoteFor(props.row
|
34
|
-
@vote-against="onVoteAgainst(props.row
|
33
|
+
@vote-for="onVoteFor(props.row)"
|
34
|
+
@vote-against="onVoteAgainst(props.row)"
|
35
35
|
)
|
36
36
|
|
37
37
|
template(#header="props")
|
@@ -59,8 +59,8 @@ div.scroll-area(style="height: 90vh; overflow-y: auto;")
|
|
59
59
|
:is-voted-for="isVotedFor"
|
60
60
|
:is-voted-against="isVotedAgainst"
|
61
61
|
:is-voted-any="isVotedAny"
|
62
|
-
@vote-for="onVoteFor(props.row
|
63
|
-
@vote-against="onVoteAgainst(props.row
|
62
|
+
@vote-for="onVoteFor(props.row)"
|
63
|
+
@vote-against="onVoteAgainst(props.row)"
|
64
64
|
)
|
65
65
|
q-td
|
66
66
|
q-btn(
|
@@ -167,11 +167,11 @@ const onAuthorizeDecision = (row: Cooperative.Document.IComplexAgenda) => {
|
|
167
167
|
emit('authorize', row)
|
168
168
|
}
|
169
169
|
|
170
|
-
const onVoteFor = (
|
171
|
-
emit('vote-for',
|
170
|
+
const onVoteFor = (row: Cooperative.Document.IComplexAgenda) => {
|
171
|
+
emit('vote-for', row)
|
172
172
|
}
|
173
173
|
|
174
|
-
const onVoteAgainst = (
|
175
|
-
emit('vote-against',
|
174
|
+
const onVoteAgainst = (row: Cooperative.Document.IComplexAgenda) => {
|
175
|
+
emit('vote-against', row)
|
176
176
|
}
|
177
177
|
</script>
|
@@ -40,7 +40,7 @@ const required_agreements = computed(() => {
|
|
40
40
|
if (required.value.includes(agreement.type)) {
|
41
41
|
// Найти, если пользователь уже подписал это соглашение
|
42
42
|
const userAgreement = userAgreements.value.find(ua => ua.type === agreement.type);
|
43
|
-
|
43
|
+
console.log('userAgreements: ', userAgreements.value)
|
44
44
|
if (userAgreement) {
|
45
45
|
// Найти соответствующий шаблон для соглашения
|
46
46
|
const template = templates.value.find(t => t.registry_id === agreement.draft_id);
|