@coopenomics/desktop 2025.5.13 → 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 +1 -0
- package/src/entities/Wallet/api/index.ts +5 -3
- package/src/processes/init-app/index.ts +2 -0
- 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/ui/ToogleDarkLight/ToogleDarkLight.vue +8 -1
- package/src/widgets/Cooperative/Documents/ListOfDocuments/ui/DocumentsTable.vue +1 -0
- package/src/widgets/Cooperative/Payments/ListOfPayments/ui/ListOfPaymentsWidget.vue +9 -10
- package/src/widgets/Participants/ui/ParticipantCard.vue +14 -6
- package/src/widgets/Participants/ui/ParticipantDetails.vue +1 -0
- package/src/widgets/Participants/ui/ParticipantsTable.vue +29 -23
- package/src/widgets/RequireAgreements/ui/RequireAgreements.vue +1 -1
package/index.html
CHANGED
@@ -20,6 +20,25 @@
|
|
20
20
|
<meta property="og:image" content="<%- SITE_IMAGE %>" />
|
21
21
|
</head>
|
22
22
|
<body>
|
23
|
+
<script>
|
24
|
+
try {
|
25
|
+
var theme = localStorage.getItem('theme-mode');
|
26
|
+
if (theme === 'dark') {
|
27
|
+
document.body.style.background = '#121212';
|
28
|
+
} else if (theme === 'light') {
|
29
|
+
document.body.style.background = '#f5f5f5';
|
30
|
+
}
|
31
|
+
} catch (e) {
|
32
|
+
console.log('error on set theme', e);
|
33
|
+
}
|
34
|
+
// Показываем лоадер только после того, как DOM готов
|
35
|
+
document.addEventListener('DOMContentLoaded', function() {
|
36
|
+
try {
|
37
|
+
var loader = document.querySelector('.loader-container');
|
38
|
+
if (loader) loader.style.display = 'flex';
|
39
|
+
} catch (e) {}
|
40
|
+
});
|
41
|
+
</script>
|
23
42
|
<style>
|
24
43
|
body {
|
25
44
|
margin: 0;
|
@@ -42,7 +61,7 @@
|
|
42
61
|
}
|
43
62
|
|
44
63
|
.loader-container {
|
45
|
-
display:
|
64
|
+
display: none;
|
46
65
|
justify-content: center;
|
47
66
|
align-items: center;
|
48
67
|
height: 100%;
|
@@ -57,7 +76,7 @@
|
|
57
76
|
border-radius: 50%;
|
58
77
|
position: relative;
|
59
78
|
animation: rotate 2s linear infinite;
|
60
|
-
border-top: 3px solid
|
79
|
+
border-top: 3px solid rgb(131, 130, 130);
|
61
80
|
border-right: 3px solid transparent;
|
62
81
|
}
|
63
82
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@coopenomics/desktop",
|
3
|
-
"version": "2025.5.
|
3
|
+
"version": "2025.5.14-1",
|
4
4
|
"description": "A Desktop Project",
|
5
5
|
"productName": "Desktop App",
|
6
6
|
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
|
@@ -24,8 +24,8 @@
|
|
24
24
|
"start": "node -r ./alias-resolver.js dist/ssr/index.js"
|
25
25
|
},
|
26
26
|
"dependencies": {
|
27
|
-
"@coopenomics/controller": "2025.5.
|
28
|
-
"@coopenomics/sdk": "2025.5.
|
27
|
+
"@coopenomics/controller": "2025.5.14-1",
|
28
|
+
"@coopenomics/sdk": "2025.5.14-1",
|
29
29
|
"@dicebear/collection": "^9.0.1",
|
30
30
|
"@dicebear/core": "^9.0.1",
|
31
31
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
@@ -49,7 +49,7 @@
|
|
49
49
|
"@wharfkit/wallet-plugin-privatekey": "^1.1.0",
|
50
50
|
"axios": "^1.2.1",
|
51
51
|
"compression": "^1.7.4",
|
52
|
-
"cooptypes": "2025.5.
|
52
|
+
"cooptypes": "2025.5.14-1",
|
53
53
|
"dompurify": "^3.1.7",
|
54
54
|
"dotenv": "^16.4.5",
|
55
55
|
"email-regex": "^5.0.0",
|
@@ -101,5 +101,5 @@
|
|
101
101
|
"npm": ">= 6.13.4",
|
102
102
|
"yarn": ">= 1.21.1"
|
103
103
|
},
|
104
|
-
"gitHead": "
|
104
|
+
"gitHead": "9d204ba496638eb0ecf93d585273dbf57687f2ec"
|
105
105
|
}
|
@@ -147,8 +147,9 @@ async function loadMethods(params: IGetPaymentMethods): Promise<IPaymentMethodDa
|
|
147
147
|
}
|
148
148
|
|
149
149
|
async function loadUserAgreements(coopname: string, username: string): Promise<SovietContract.Tables.Agreements.IAgreement[]> {
|
150
|
-
|
151
|
-
|
150
|
+
|
151
|
+
console.log('coopname: ', coopname, 'username: ', username)
|
152
|
+
const result = await fetchTable(
|
152
153
|
SovietContract.contractName.production,
|
153
154
|
coopname,
|
154
155
|
SovietContract.Tables.Agreements.tableName,
|
@@ -157,7 +158,8 @@ async function loadUserAgreements(coopname: string, username: string): Promise<S
|
|
157
158
|
LimitsList.None,
|
158
159
|
'secondary'
|
159
160
|
)
|
160
|
-
|
161
|
+
console.log('result: ', result)
|
162
|
+
return result as SovietContract.Tables.Agreements.IAgreement[];
|
161
163
|
|
162
164
|
}
|
163
165
|
|
@@ -5,8 +5,10 @@ import type { Router } from 'vue-router'
|
|
5
5
|
import { useBranchOverlayProcess } from '../watch-branch-overlay'
|
6
6
|
import { setupNavigationGuard } from '../navigation-guard-setup'
|
7
7
|
import { useInitExtensionsProcess } from 'src/processes/init-installed-extensions'
|
8
|
+
import { applyThemeFromStorage } from 'src/shared/lib/utils'
|
8
9
|
|
9
10
|
export async function useInitAppProcess(router: Router) {
|
11
|
+
applyThemeFromStorage()
|
10
12
|
const system = useSystemStore()
|
11
13
|
await system.loadSystemInfo()
|
12
14
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import {
|
2
|
+
AccountTypes,
|
3
|
+
type IAccount,
|
4
|
+
} from 'src/entities/Account/types'
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Функция для получения отформатированного имени участника
|
8
|
+
* @param account - объект аккаунта пользователя
|
9
|
+
* @returns форматированное имя/наименование
|
10
|
+
*/
|
11
|
+
export const getName = (account: IAccount) => {
|
12
|
+
const d = account.private_account
|
13
|
+
if (!d) return ''
|
14
|
+
switch (d.type) {
|
15
|
+
case AccountTypes.individual:
|
16
|
+
return `${d.individual_data?.last_name} ${d.individual_data?.first_name} ${d.individual_data?.middle_name}`
|
17
|
+
case AccountTypes.entrepreneur:
|
18
|
+
return `ИП ${d.entrepreneur_data?.last_name} ${d.entrepreneur_data?.first_name} ${d.entrepreneur_data?.middle_name}`
|
19
|
+
case AccountTypes.organization:
|
20
|
+
return d.organization_data?.short_name
|
21
|
+
default:
|
22
|
+
return ''
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { LocalStorage } from 'quasar';
|
2
|
+
import { Dark } from 'quasar';
|
3
|
+
|
4
|
+
const THEME_KEY = 'theme-mode';
|
5
|
+
|
6
|
+
export function saveThemeToStorage(isDark: boolean) {
|
7
|
+
if (process.env.CLIENT) {
|
8
|
+
LocalStorage.set(THEME_KEY, isDark ? 'dark' : 'light');
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
export function getThemeFromStorage(): 'dark' | 'light' | null {
|
13
|
+
if (process.env.CLIENT) {
|
14
|
+
const saved = LocalStorage.getItem(THEME_KEY);
|
15
|
+
if (saved === 'dark' || saved === 'light') return saved;
|
16
|
+
return null;
|
17
|
+
}
|
18
|
+
return null;
|
19
|
+
}
|
20
|
+
|
21
|
+
export function applyThemeFromStorage() {
|
22
|
+
if (process.env.CLIENT) {
|
23
|
+
const saved = getThemeFromStorage();
|
24
|
+
if (saved === 'dark') {
|
25
|
+
Dark.set(true);
|
26
|
+
} else if (saved === 'light') {
|
27
|
+
Dark.set(false);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
@@ -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 {
|
@@ -53,6 +53,7 @@ div.scroll-area(style="height: 90vh; overflow-y: auto;")
|
|
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"
|
@@ -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
|
@@ -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"
|
@@ -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")
|
@@ -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>
|
@@ -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);
|