@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.
Files changed (59) hide show
  1. package/index.html +21 -2
  2. package/package.json +5 -5
  3. package/src/entities/Registrator/model/store.ts +16 -11
  4. package/src/entities/Wallet/api/index.ts +5 -3
  5. package/src/features/Agreementer/SignAgreementDialog/model/index.ts +5 -3
  6. package/src/features/Agreementer/SignAgreementDialog/ui/SignAgreementDialog.vue +1 -1
  7. package/src/features/Decision/AuthorizeAndExecDecision/model/index.ts +6 -9
  8. package/src/features/Decision/CreateProject/model/index.ts +1 -1
  9. package/src/features/Decision/VoteAgainstDecision/model/index.ts +14 -2
  10. package/src/features/Decision/VoteForDecision/model/index.ts +9 -5
  11. package/src/features/FreeDecision/CreateProject/model/index.ts +1 -1
  12. package/src/features/Meet/CloseMeetWithDecision/model/index.ts +13 -13
  13. package/src/features/Meet/CreateMeet/model/index.ts +1 -1
  14. package/src/features/Meet/RestartMeet/model/index.ts +6 -3
  15. package/src/features/Request/AcceptRequest/api/index.ts +3 -10
  16. package/src/features/Request/ConfirmRecieveOnRequest/api/index.ts +4 -9
  17. package/src/features/Request/ConfirmSupplyOnRequest/api/index.ts +6 -11
  18. package/src/features/Request/ConfirmSupplyOnRequest/ui/ConfirmSupplyOnRequestButton.vue +1 -1
  19. package/src/features/Request/CreateChildOrder/model/index.ts +35 -30
  20. package/src/features/Request/CreateChildOrder/ui/CreateChildOrderButton/CreateChildOrderButton.vue +20 -15
  21. package/src/features/Request/DisputeOnRequest/api/index.ts +19 -24
  22. package/src/features/Request/DisputeOnRequest/ui/DisputeOnRequestButton.vue +1 -1
  23. package/src/features/Request/RecieveOnRequest/api/index.ts +6 -11
  24. package/src/features/Request/RecieveOnRequest/ui/RecieveOnRequestButton.vue +1 -1
  25. package/src/features/Request/SupplyOnRequest/api/index.ts +18 -27
  26. package/src/features/Union/AddCooperative/ui/AddCooperativeForm.vue +7 -5
  27. package/src/features/User/CreateUser/api/index.ts +28 -10
  28. package/src/features/User/CreateUser/model/index.ts +39 -31
  29. package/src/pages/Cooperative/ListOfAgenda/ui/ListOfAgendaQuestions.vue +8 -8
  30. package/src/pages/Cooperative/ListOfParticipants/ui/ListOfParticipantsPage.vue +3 -3
  31. package/src/pages/Registrator/SignUp/EmailInput.vue +0 -7
  32. package/src/pages/Union/ConnectionAgreement/ConnectionAgreementPage.vue +1 -1
  33. package/src/processes/init-app/index.ts +2 -0
  34. package/src/processes/process-decisions/index.ts +32 -29
  35. package/src/processes/select-branch/index.ts +1 -1
  36. package/src/shared/api/indexDB.ts +0 -1
  37. package/src/shared/lib/document/model/const.ts +30 -0
  38. package/src/shared/lib/document/model/entity.ts +33 -21
  39. package/src/shared/lib/document/model/index.ts +1 -1
  40. package/src/shared/lib/document/model/types.ts +2 -3
  41. package/src/shared/lib/types/document/index.ts +11 -13
  42. package/src/shared/lib/types/user/IUserData.ts +5 -6
  43. package/src/shared/lib/types/user/index.ts +1 -11
  44. package/src/shared/lib/utils/account.ts +24 -0
  45. package/src/shared/lib/utils/index.ts +2 -0
  46. package/src/shared/lib/utils/theme.ts +30 -0
  47. package/src/shared/store/index.ts +9 -5
  48. package/src/shared/ui/BaseDocument/BaseDocument.vue +43 -42
  49. package/src/shared/ui/ComplexDocument/ComplexDocument.vue +7 -5
  50. package/src/shared/ui/ToogleDarkLight/ToogleDarkLight.vue +8 -1
  51. package/src/shared/ui/ZodForm/ZodForm.vue +1 -1
  52. package/src/widgets/Cooperative/Documents/ListOfDocuments/ui/DocumentsTable.vue +3 -2
  53. package/src/widgets/Cooperative/Payments/ListOfPayments/ui/ListOfPaymentsWidget.vue +9 -10
  54. package/src/widgets/Meets/MeetDetailsVoting/model.ts +4 -4
  55. package/src/widgets/Participants/ui/ParticipantCard.vue +17 -9
  56. package/src/widgets/Participants/ui/ParticipantDetails.vue +7 -6
  57. package/src/widgets/Participants/ui/ParticipantsTable.vue +29 -23
  58. package/src/widgets/Questions/ui/QuestionsTable/QuestionsTable.vue +8 -8
  59. 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.meta.title}}
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="doc.hash == regeneratedHash ? 'teal' : 'red'").text-center.q-pa-xs
15
- q-icon(:name="doc.hash == regeneratedHash ? 'check_circle' : 'cancel'" ).q-mr-sm
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 {{ doc.hash }}
17
+ p.q-mr-lg.q-ml-lg.text-grey {{ documentAggregate?.document?.doc_hash }}
18
18
 
19
19
  // Показываем все подписи (если это агрегат документа)
20
- template(v-if="documentAggregate && documentAggregate.signatures && documentAggregate.signatures.length > 0")
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.signer)}`"
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="signatures_verified[index] ? 'teal' : 'red'").text-center.q-pa-xs
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.signer) }}
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="signatures_verified[index] ? 'teal' : 'red'").text-center.q-pa-xs
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="signatures_verified[index] ? 'teal' : 'red'").text-center.q-pa-xs
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="signatures_verified[index] ? 'teal' : 'red'").text-center.q-pa-xs
54
- q-icon(:name="signatures_verified[index] ? 'check_circle' : 'cancel'").q-mr-sm
55
- span Статус подписи: {{ signatures_verified[index] ? 'Верифицирована' : 'Не верифицирована' }}
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.meta}, {skip_save: true})
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.html));
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.binary);
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
- signatures_verified.value = props.documentAggregate.signatures.map(signatureData => {
143
- try {
144
- if (signatureData.public_key && signatureData.signature) {
145
- const public_key = PublicKey.from(signatureData.public_key)
146
- const signature = Signature.from(signatureData.signature)
147
- const hash = doc.value.hash
148
- const is_valid = signature.verifyDigest(hash, public_key)
149
- return is_valid
150
- } else {
151
- return signatureData.is_valid
152
- }
153
- } catch (error) {
154
- console.error('Ошибка при верификации подписи:', error)
155
- return false
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.binary}`;
171
- link.download = doc.value.full_title ? doc.value.full_title : `${doc.value.meta.title} - ${doc.value.meta.username} - ${doc.value.meta.created_at}.pdf`;
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(() => signatures_verified.value.some(v => v === false))
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="$q.dark.toggle()")
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, QCard } from 'quasar';
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.id}}
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: 'От кого', field: 'username', sortable: true },
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.text-caption Е-почта:
9
- div.text-subtitle1.q-mb-xs {{ participant.provider_account?.email || 'Не указана' }}
10
- div.text-caption Аккаунт:
11
- div.text-subtitle1.q-mb-xs {{ participant.username }}
12
- div.text-caption Зарегистрирован:
13
- div.text-subtitle1 {{ formatDate(participant.blockchain_account?.created) }}
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.Individual:
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.Entrepreneur:
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.Organization:
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.Individual: return EditableIndividualCard
61
- case AccountTypes.Entrepreneur: return EditableEntrepreneurCard
62
- case AccountTypes.Organization: return EditableOrganizationCard
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.Individual: return account.private_account.individual_data
70
- case AccountTypes.Entrepreneur: return account.private_account.entrepreneur_data
71
- case AccountTypes.Organization: return account.private_account.organization_data
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
- q-td {{ formatDate(props.row.blockchain_account?.created) }}
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: 'Зарегистрирован', field: 'created_at', sortable: true },
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.table.id)"
34
- @vote-against="onVoteAgainst(props.row.table.id)"
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.table.id)"
63
- @vote-against="onVoteAgainst(props.row.table.id)"
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 = (decision_id: number) => {
171
- emit('vote-for', decision_id)
170
+ const onVoteFor = (row: Cooperative.Document.IComplexAgenda) => {
171
+ emit('vote-for', row)
172
172
  }
173
173
 
174
- const onVoteAgainst = (decision_id: number) => {
175
- emit('vote-against', decision_id)
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);