@coopenomics/desktop 2.2.3 → 2.2.5

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/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.2.5](https://github.com/coopenomics/monocoop/compare/v2.2.4...v2.2.5) (2025-01-18)
7
+
8
+ **Note:** Version bump only for package @coopenomics/desktop
9
+
10
+
11
+
12
+
13
+
14
+ ## [2.2.4](https://github.com/coopenomics/monocoop/compare/v2.2.0...v2.2.4) (2025-01-17)
15
+
16
+ **Note:** Version bump only for package @coopenomics/desktop
17
+
18
+
19
+
20
+
21
+
6
22
  ## [2.2.3](https://github.com/coopenomics/monocoop/compare/v2.2.0...v2.2.3) (2025-01-16)
7
23
 
8
24
  **Note:** Version bump only for package @coopenomics/desktop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coopenomics/desktop",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "description": "A Desktop Project",
5
5
  "productName": "Desktop App",
6
6
  "author": "Alex Ant <dacom.dark.sun@gmail.com>",
@@ -20,8 +20,8 @@
20
20
  "prepublishOnly": "npm run build:lib"
21
21
  },
22
22
  "dependencies": {
23
- "@coopenomics/controller": "2.2.3",
24
- "@coopenomics/sdk": "2.2.3",
23
+ "@coopenomics/controller": "2.2.5",
24
+ "@coopenomics/sdk": "2.2.5",
25
25
  "@dicebear/collection": "^9.0.1",
26
26
  "@dicebear/core": "^9.0.1",
27
27
  "@fortawesome/fontawesome-svg-core": "^6.5.2",
@@ -45,7 +45,7 @@
45
45
  "@wharfkit/wallet-plugin-privatekey": "^1.1.0",
46
46
  "axios": "^1.2.1",
47
47
  "compression": "^1.7.4",
48
- "cooptypes": "^2.2.3",
48
+ "cooptypes": "2.2.5",
49
49
  "dompurify": "^3.1.7",
50
50
  "dotenv": "^16.4.5",
51
51
  "email-regex": "^5.0.0",
@@ -94,5 +94,5 @@
94
94
  "npm": ">= 6.13.4",
95
95
  "yarn": ">= 1.21.1"
96
96
  },
97
- "gitHead": "40fb5c80eb4136e82813fd553703f4a7926166a0"
97
+ "gitHead": "97b21a9d69b6c387a1a7f2c32642d29c0898694e"
98
98
  }
@@ -24,6 +24,17 @@ export const manifest = {
24
24
  path: '/:coopname/user',
25
25
  name: 'home',
26
26
  children: [
27
+ {
28
+ meta: {
29
+ title: 'Подключение',
30
+ icon: 'fas fa-link',
31
+ roles: ['user'],
32
+ conditions: 'isCoop === true && coopname === "voskhod"',
33
+ },
34
+ path: '/:coopname/connect',
35
+ name: 'connect',
36
+ component: markRaw(ConnectionPage),
37
+ },
27
38
  {
28
39
  meta: {
29
40
  title: 'Карта пайщика',
@@ -141,17 +152,7 @@ export const manifest = {
141
152
  component: markRaw(UnionPageListOfCooperatives),
142
153
 
143
154
  },
144
- {
145
- // meta: {
146
- // title: 'Подключения',
147
- // icon: 'fas fa-link',
148
- // roles: ['chairman', 'member'],
149
- // },
150
- path: '/:coopname/connect',
151
- name: 'connect',
152
- component: markRaw(ConnectionPage),
153
155
 
154
- },
155
156
  {
156
157
  path: '/:coopname/contacts',
157
158
  name: 'contacts',
@@ -16,6 +16,7 @@ interface RouteMeta {
16
16
  title: string;
17
17
  icon: string;
18
18
  roles: string[];
19
+ conditions: string;
19
20
  }
20
21
 
21
22
  export interface IRoute {
@@ -6,7 +6,7 @@ export type ISchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'object'
6
6
 
7
7
  export type ISchemaProperty = {
8
8
  type?: ISchemaType;
9
- description?: Types.DeserializedDescriptionOfExtension
9
+ description?: Types.Controller.DeserializedDescriptionOfExtension
10
10
  default?: any;
11
11
  required?: string[];
12
12
  properties?: ISchemaProperty;
package/src/env.d.ts CHANGED
@@ -21,6 +21,7 @@ declare module 'vue-router' {
21
21
  // Расширяем интерфейс RouteMeta, добавляя новые свойства
22
22
  interface RouteMeta {
23
23
  roles?: string[];
24
+ conditions?: string;
24
25
  agreements?: string[]
25
26
  title: string
26
27
  icon: string
@@ -7,7 +7,6 @@ import { IGeneratedAccount, ISendStatement } from 'src/shared/lib/types/user';
7
7
  import { useSessionStore } from 'src/entities/Session';
8
8
  import { useGlobalStore } from 'src/shared/store';
9
9
  import { COOPNAME } from 'src/shared/config';
10
- import { DigitalDocument } from 'src/shared/lib/document';
11
10
  import { IObjectedDocument } from 'src/shared/lib/types/document';
12
11
  import {
13
12
  ICreatedPayment,
@@ -17,7 +16,8 @@ import {
17
16
  } from 'src/entities/User';
18
17
  import { useRegistratorStore } from 'src/entities/Registrator'
19
18
  import { IEntrepreneurData, IIndividualData, IOrganizationData, IUserData } from 'src/shared/lib/types/user/IUserData';
20
- import { Cooperative } from 'cooptypes';
19
+ import { client } from 'src/shared/api/client';
20
+ import { Mutations } from '@coopenomics/sdk';
21
21
 
22
22
  export interface ICreateUser {
23
23
  email: string;
@@ -56,113 +56,124 @@ export function useCreateUser() {
56
56
 
57
57
 
58
58
  async function signStatement(): Promise<IObjectedDocument> {
59
- const data: Cooperative.Registry.ParticipantApplication.Action = {
60
- registry_id: Cooperative.Registry.ParticipantApplication.registry_id,
61
- signature: store.signature,
62
- skip_save: false,
63
- coopname: COOPNAME,
64
- username: store.account.username,
65
- braname: store.selectedBranch,
66
- links: [store.walletAgreement.hash, store.privacyAgreement.hash, store.signatureAgreement.hash, store.userAgreement.hash]
59
+ const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
60
+ data: {
61
+ signature: store.signature,
62
+ skip_save: false,
63
+ coopname: COOPNAME,
64
+ username: store.account.username,
65
+ braname: store.selectedBranch,
66
+ links: [store.walletAgreement.hash, store.privacyAgreement.hash, store.signatureAgreement.hash, store.userAgreement.hash]
67
+ }
67
68
  }
68
69
 
69
- const document = await new DigitalDocument().generate<Cooperative.Registry.ParticipantApplication.Action>(data);
70
- const globalStore = useGlobalStore();
71
- const digital_signature = await globalStore.signDigest(document.hash);
70
+ const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
71
+ Mutations.Participants.GenerateParticipantApplication.mutation,
72
+ { variables }
73
+ );
72
74
 
73
- store.statement = {
74
- hash: document.hash,
75
- meta: document.meta,
76
- public_key: digital_signature.public_key,
77
- signature: digital_signature.signature,
78
- } as IObjectedDocument;
75
+ store.statement = await client.Document.signDocument(result)
79
76
 
80
77
  return store.statement;
81
78
  }
82
79
 
83
80
  async function signPrivacyAgreement(): Promise<IObjectedDocument> {
84
- const data: Cooperative.Registry.PrivacyPolicy.Action= {
85
- registry_id: Cooperative.Registry.PrivacyPolicy.registry_id,
86
- coopname: COOPNAME,
87
- username: store.account.username,
88
- };
81
+ const variables: Mutations.Agreements.GeneratePrivacyAgreement.IInput = {
82
+ data: {
83
+ coopname: COOPNAME,
84
+ username: store.account.username,
85
+ }
86
+ }
89
87
 
90
- const document = new DigitalDocument();
91
- await document.generate(data);
92
- await document.sign();
88
+ const { [Mutations.Agreements.GeneratePrivacyAgreement.name]: result } = await client.Mutation(
89
+ Mutations.Agreements.GeneratePrivacyAgreement.mutation,
90
+ { variables }
91
+ );
93
92
 
94
- store.privacyAgreement = document.signedDocument as IObjectedDocument;
93
+ store.privacyAgreement = await client.Document.signDocument(result)
95
94
 
96
95
  return store.privacyAgreement;
97
96
  }
98
97
 
99
98
  async function signSignatureAgreement(): Promise<IObjectedDocument> {
100
- const data: Cooperative.Registry.RegulationElectronicSignature.Action= {
101
- registry_id: Cooperative.Registry.RegulationElectronicSignature.registry_id,
102
- coopname: COOPNAME,
103
- username: store.account.username,
104
- };
99
+ const variables: Mutations.Agreements.GenerateSignatureAgreement.IInput = {
100
+ data: {
101
+ coopname: COOPNAME,
102
+ username: store.account.username,
103
+ }
104
+ }
105
105
 
106
- const document = new DigitalDocument();
107
- await document.generate(data);
108
- await document.sign();
106
+ const { [Mutations.Agreements.GenerateSignatureAgreement.name]: result } = await client.Mutation(
107
+ Mutations.Agreements.GenerateSignatureAgreement.mutation,
108
+ { variables }
109
+ );
109
110
 
110
- store.signatureAgreement = document.signedDocument as IObjectedDocument;
111
+ store.signatureAgreement = await client.Document.signDocument(result)
111
112
 
112
113
  return store.signatureAgreement;
114
+
113
115
  }
114
116
 
115
117
 
116
118
  async function signUserAgreement(): Promise<IObjectedDocument> {
117
- const data: Cooperative.Registry.UserAgreement.Action= {
118
- registry_id: Cooperative.Registry.UserAgreement.registry_id,
119
- coopname: COOPNAME,
120
- username: store.account.username,
121
- };
119
+ const variables: Mutations.Agreements.GenerateUserAgreement.IInput = {
120
+ data: {
121
+ coopname: COOPNAME,
122
+ username: store.account.username,
123
+ }
124
+ }
122
125
 
123
- const document = new DigitalDocument();
124
- await document.generate(data);
125
- await document.sign();
126
+ const { [Mutations.Agreements.GenerateUserAgreement.name]: result } = await client.Mutation(
127
+ Mutations.Agreements.GenerateUserAgreement.mutation,
128
+ { variables }
129
+ );
126
130
 
127
- store.userAgreement = document.signedDocument as IObjectedDocument;
131
+ store.userAgreement = await client.Document.signDocument(result)
128
132
 
129
133
  return store.userAgreement;
134
+
130
135
  }
131
136
 
132
137
 
133
138
 
134
139
 
135
140
  async function signWalletAgreement(): Promise<IObjectedDocument> {
136
- const data: Cooperative.Registry.WalletAgreement.Action= {
137
- registry_id: Cooperative.Registry.WalletAgreement.registry_id,
138
- coopname: COOPNAME,
139
- username: store.account.username,
140
- };
141
-
142
- const document = new DigitalDocument();
143
- await document.generate(data);
144
- await document.sign();
141
+ const variables: Mutations.Agreements.GenerateWalletAgreement.IInput = {
142
+ data: {
143
+ coopname: COOPNAME,
144
+ username: store.account.username,
145
+ }
146
+ }
145
147
 
146
- store.walletAgreement = document.signedDocument as IObjectedDocument;
148
+ const { [Mutations.Agreements.GenerateWalletAgreement.name]: result } = await client.Mutation(
149
+ Mutations.Agreements.GenerateWalletAgreement.mutation,
150
+ { variables }
151
+ );
147
152
 
148
- console.log('walletAgreement: ', store.walletAgreement)
153
+ store.walletAgreement = await client.Document.signDocument(result)
149
154
 
150
155
  return store.walletAgreement;
151
156
  }
152
157
 
153
158
 
154
159
  async function generateStatementWithoutSignature() {
160
+ const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
161
+ data: {
162
+ signature: '',
163
+ skip_save: true,
164
+ coopname: COOPNAME,
165
+ username: store.account.username,
166
+ braname: store.selectedBranch,
167
+ }
168
+ }
155
169
 
156
- const document = await new DigitalDocument().generate<Cooperative.Registry.ParticipantApplication.Action>({
157
- signature: '',
158
- skip_save: true,
159
- coopname: COOPNAME,
160
- username: store.account.username,
161
- braname: store.selectedBranch,
162
- registry_id: Cooperative.Registry.ParticipantApplication.registry_id
163
- });
170
+ const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
171
+ Mutations.Participants.GenerateParticipantApplication.mutation,
172
+ { variables }
173
+ );
174
+
175
+ return result;
164
176
 
165
- return document;
166
177
  }
167
178
 
168
179
  async function createUser(
@@ -43,7 +43,7 @@ div
43
43
  <script lang="ts" setup>
44
44
  import { ref, computed, watch, onMounted } from 'vue'
45
45
  import { useCreateUser } from 'src/features/User/CreateUser'
46
- import { FailAlert } from 'src/shared/api';
46
+ import { failAlert } from 'src/shared/api';
47
47
  import { Loader } from 'src/shared/ui/Loader';
48
48
  import { ReadAgreementDialog } from 'src/features/Agreementer/ReadAgreementDialog';
49
49
  import { useAgreementStore } from 'src/entities/Agreement'
@@ -70,7 +70,7 @@ const loadStatement = async (): Promise<void> => {
70
70
  isLoading.value = false
71
71
  } catch (e: any) {
72
72
  isLoading.value = false
73
- FailAlert(e.message)
73
+ failAlert(e.message)
74
74
  }
75
75
  }
76
76
 
@@ -1,189 +1,157 @@
1
- <template lang='pug'>
2
- div
3
- q-step(:name='store.steps.SignStatement', title='Подпишите заявление на вступление', :done='store.isStepDone("SignStatement")')
4
- div(v-if='onSign')
5
- Loader(:text='loadingText')
6
- div(v-else)
7
- .bg-grey-2(v-if='!onSign' ref='around', style='border: 0.1px solid grey; min-height: 300px;')
8
- canvas(
9
- ref='canvas',
10
- @touchstart='startDrawing',
11
- @touchmove='draw',
12
- @touchend='endDrawing',
13
- @mousedown='startDrawing',
14
- @mousemove='draw',
15
- @mouseup='endDrawing'
1
+ <template lang="pug">
2
+ div
3
+ q-step(
4
+ :name="store.steps.SignStatement"
5
+ title="Подпишите заявление на вступление"
6
+ :done="store.isStepDone('SignStatement')"
7
+ )
8
+ div(v-if="onSign")
9
+ Loader(:text="loadingText")
10
+
11
+ div(v-else)
12
+ // Контейнер, внутри которого класс Canvas создаёт <canvas>
13
+ .bg-grey-2(
14
+ v-if="!onSign"
15
+ ref="around"
16
+ style="border: 0.1px solid grey; min-height: 300px;"
16
17
  )
17
- p.text-center.full-width Оставьте собственноручную подпись в рамке
18
- .q-mt-lg.q-mb-lg
19
- q-btn.col-md-4.col-xs-12(flat, @click='store.prev()')
20
- i.fa.fa-arrow-left
21
- span.q-ml-md назад
22
- q-btn.col-md-4.col-xs-12(flat, @click='clearCanvas')
23
- span.q-ml-md очистить
24
- q-btn.col-md-4.col-xs-12(color='primary', label='Продолжить', @click='setSignature')
25
-
26
- </template>
27
- <script lang="ts" setup>
28
- import { ref, watch, onBeforeMount, nextTick, onMounted } from 'vue'
29
- import { useCreateUser } from 'src/features/User/CreateUser'
30
- import { Notify } from 'quasar'
31
- import { FailAlert } from 'src/shared/api';
32
- import { Loader } from 'src/shared/ui/Loader';
33
-
34
- import { useRegistratorStore } from 'src/entities/Registrator'
35
- const store = useRegistratorStore()
36
-
37
- const createUser = useCreateUser()
38
-
39
- const around = ref()
40
- const onSign = ref(false)
41
- const loadingText = ref('')
42
-
43
- const canvas = ref<HTMLCanvasElement | null>(null)
44
- const drawing = ref<boolean>(false)
45
- let context: CanvasRenderingContext2D | null = null
46
- let lastX = 0
47
- let lastY = 0
48
-
49
- const windowWidth = ref<number>()
50
- const windowHeight = ref<number>()
51
-
52
- const setSignature = async (): Promise<void> => {
53
- if (!context || !canvas.value) {
54
- Notify.create({
55
- message: 'Пожалуйста, оставьте собственноручную подпись в окне',
56
- color: 'negative',
57
- })
58
- return
18
+ p.text-center.full-width Оставьте собственноручную подпись в рамке
19
+ .q-mt-lg.q-mb-lg
20
+ q-btn.col-md-4.col-xs-12(flat @click="store.prev()")
21
+ i.fa.fa-arrow-left
22
+ span.q-ml-md назад
23
+ q-btn.col-md-4.col-xs-12(flat @click="clearCanvas")
24
+ span.q-ml-md очистить
25
+ q-btn.col-md-4.col-xs-12(color="primary" label="Продолжить" @click="setSignature")
26
+ </template>
27
+
28
+ <script lang="ts" setup>
29
+ import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
30
+ import { Notify } from 'quasar'
31
+ import { failAlert, FailAlert } from 'src/shared/api'
32
+ import { Loader } from 'src/shared/ui/Loader'
33
+ import { useRegistratorStore } from 'src/entities/Registrator'
34
+ import { useCreateUser } from 'src/features/User/CreateUser'
35
+
36
+ // Импортируем класс
37
+ import { Classes } from '@coopenomics/sdk'
38
+ import { client } from 'src/shared/api/client'
39
+
40
+ const store = useRegistratorStore()
41
+ const createUser = useCreateUser()
42
+
43
+ const around = ref<HTMLElement | null>(null)
44
+ const onSign = ref(false)
45
+ const loadingText = ref('')
46
+
47
+ // Экземпляр Canvas
48
+ let canvasClass: Classes.Canvas | null = null
49
+
50
+ /**
51
+ * Инициализация Canvas с задержкой
52
+ */
53
+ const initCanvas = () => {
54
+
55
+ // Ждём 200ms, чтобы Quasar завершил рендеринг
56
+ setTimeout(() => {
57
+ if (around.value)
58
+ canvasClass = new Classes.Canvas(around.value, {
59
+ lineWidth: 5,
60
+ strokeStyle: '#000',
61
+ })
62
+ }, 200)
59
63
  }
60
64
 
65
+ /**
66
+ * Следим за текущим шагом
67
+ */
68
+ watch(
69
+ () => store.state.step,
70
+ (newStep) => {
71
+ if (newStep === store.steps.SignStatement) {
72
+ nextTick(() => initCanvas())
73
+ }
74
+ }
75
+ )
76
+
77
+ /**
78
+ * Если при загрузке уже SignStatement — инициализируем
79
+ */
80
+ onMounted(() => {
81
+ if (store.state.step === store.steps.SignStatement) {
82
+ nextTick(() => initCanvas())
83
+ }
84
+ })
61
85
 
62
- const imgData = context.getImageData(0, 0, canvas.value.width, canvas.value.height).data
63
- const isEmpty = !imgData.some((channel) => channel !== 0)
64
- const sign = canvas.value.toDataURL('image/png')
86
+ /**
87
+ * При размонтировании снимаем слушатели
88
+ */
89
+ onBeforeUnmount(() => {
90
+ canvasClass?.destroy()
91
+ })
65
92
 
66
- if (!sign || isEmpty) {
67
- FailAlert('Пожалуйста, оставьте собственноручную подпись в окне')
68
- return
93
+ /**
94
+ * Очистка холста
95
+ */
96
+ const clearCanvas = () => {
97
+ canvasClass?.clearCanvas()
69
98
  }
70
99
 
71
- try {
72
- onSign.value = true
73
- store.state.signature = sign
74
-
75
- loadingText.value = 'Подписываем положение о ЦПП "Цифровой Кошелёк"'
76
-
77
- await createUser.signWalletAgreement()
78
-
79
- loadingText.value = 'Подписываем соглашение о политике конфиденциальности'
80
-
81
- await createUser.signPrivacyAgreement()
82
-
83
- loadingText.value = 'Подписываем соглашение о порядке и правилах использования ЭЦП'
84
-
85
- await createUser.signSignatureAgreement()
86
-
87
- loadingText.value = 'Подписываем пользовательское соглашение'
88
-
89
- await createUser.signUserAgreement()
90
-
91
- loadingText.value = 'Подписываем заявление'
92
-
93
- await createUser.signStatement()
94
-
95
- //посылаем
96
- await createUser.sendStatementAndAgreements()
97
- loadingText.value = ''
100
+ /**
101
+ * Получение подписи + проверка пустоты
102
+ */
103
+ const setSignature = async () => {
104
+ if (!canvasClass) {
105
+ Notify.create({
106
+ message: 'Пожалуйста, оставьте собственноручную подпись в окне',
107
+ color: 'negative',
108
+ })
109
+ return
110
+ }
98
111
 
99
- onSign.value = false
100
- store.next()
101
- } catch (e: any) {
102
- onSign.value = false
103
- FailAlert(e.message)
104
- }
112
+ const sign = canvasClass.getSignature()
113
+ // Проверим, есть ли хоть один ненулевой пиксель
114
+ const ctx = canvasClass.ctx
115
+ const { width, height } = canvasClass.canvas
116
+ const data = ctx.getImageData(0, 0, width, height).data
117
+ const isEmpty = !data.some((channel) => channel !== 0)
105
118
 
119
+ if (!sign || isEmpty) {
120
+ FailAlert('Пожалуйста, оставьте собственноручную подпись в окне')
121
+ return
122
+ }
106
123
 
107
- }
124
+ try {
125
+ onSign.value = true
126
+ store.state.signature = sign
108
127
 
109
- const init = (): void => {
110
- prepareCanvas()
111
- }
128
+ // устанавливаем ключ для подписи документов
129
+ client.Document.setWif(store.state.account.private_key)
112
130
 
113
- watch(() => store.state.step, (newStep) => {
114
- if (newStep == store.steps.SignStatement) {
115
- init()
116
- }
117
- })
131
+ loadingText.value = 'Подписываем положение о ЦПП "Цифровой Кошелёк"'
132
+ await createUser.signWalletAgreement()
118
133
 
119
- window.addEventListener('resize', () => {
120
- prepareCanvas()
121
- })
134
+ loadingText.value = 'Подписываем соглашение о политике конфиденциальности'
135
+ await createUser.signPrivacyAgreement()
122
136
 
123
- onBeforeMount(() => {
124
- window.removeEventListener('resize', prepareCanvas)
125
- })
137
+ loadingText.value = 'Подписываем соглашение о порядке и правилах использования ЭЦП'
138
+ await createUser.signSignatureAgreement()
126
139
 
127
- onMounted(() => {
128
- init()
129
- })
140
+ loadingText.value = 'Подписываем пользовательское соглашение'
141
+ await createUser.signUserAgreement()
130
142
 
131
- const prepareCanvas = (): void => {
132
- nextTick(() => {
133
- windowWidth.value = around.value?.offsetWidth || 0
134
- windowHeight.value = around.value?.offsetHeight || 0
143
+ loadingText.value = 'Подписываем заявление'
144
+ await createUser.signStatement()
135
145
 
136
- context = canvas.value?.getContext('2d') ?? null
146
+ // Отправка
147
+ await createUser.sendStatementAndAgreements()
137
148
 
138
- if (context) {
139
- if (canvas.value) {
140
- canvas.value.width = windowWidth.value || 0
141
- canvas.value.height = windowHeight.value || 0
142
- }
143
- context.strokeStyle = 'grey'
144
- context.lineWidth = 5
145
- context.lineJoin = 'round'
146
- context.lineCap = 'round'
147
- context.strokeStyle = '#000'
149
+ loadingText.value = ''
150
+ onSign.value = false
151
+ store.next()
152
+ } catch (err: any) {
153
+ onSign.value = false
154
+ failAlert(err)
148
155
  }
149
- })
150
- }
151
-
152
- const clearCanvas = (): void => {
153
- context?.clearRect(0, 0, canvas.value?.width || 0, canvas.value?.height || 0)
154
- }
155
-
156
- const startDrawing = (e: MouseEvent | TouchEvent): void => {
157
- e.preventDefault()
158
- drawing.value = true
159
- const rect = canvas.value?.getBoundingClientRect()
160
- lastX =
161
- e instanceof MouseEvent
162
- ? e.clientX - (rect?.left || 0)
163
- : e.touches[0].clientX - (rect?.left || 0)
164
- lastY =
165
- e instanceof MouseEvent ? e.clientY - (rect?.top || 0) : e.touches[0].clientY - (rect?.top || 0)
166
- }
167
-
168
- const endDrawing = (): void => {
169
- drawing.value = false
170
- }
171
-
172
- const draw = (e: MouseEvent | TouchEvent): void => {
173
- e.preventDefault()
174
- if (!drawing.value) return
175
- context?.beginPath()
176
- context?.moveTo(lastX, lastY)
177
- const rect = canvas.value?.getBoundingClientRect()
178
- const x =
179
- e instanceof MouseEvent
180
- ? e.clientX - (rect?.left || 0)
181
- : e.touches[0].clientX - (rect?.left || 0)
182
- const y =
183
- e instanceof MouseEvent ? e.clientY - (rect?.top || 0) : e.touches[0].clientY - (rect?.top || 0)
184
- context?.lineTo(x, y)
185
- context?.stroke()
186
- lastX = x
187
- lastY = y
188
- }
189
- </script>
156
+ }
157
+ </script>
@@ -1,8 +1,8 @@
1
- import {createClient} from '@coopenomics/sdk'
1
+ import { Client } from '@coopenomics/sdk'
2
2
  import { BACKEND_URL, CHAIN_ID, CHAIN_URL } from '../config'
3
3
 
4
4
  // Создаем и экспортируем экземпляр API-клиента
5
- export const client = createClient({
5
+ export const client = Client.create({
6
6
  api_url: BACKEND_URL + '/v1/graphql',
7
7
  headers: {
8
8
  'Content-Type': 'application/json',
@@ -25,7 +25,7 @@ q-list(
25
25
  import { useRoute, useRouter } from 'vue-router';
26
26
  import { useDesktopStore } from 'src/entities/Desktop/model';
27
27
  import { type IRoute } from 'src/entities/Desktop/model/types';
28
- import { COOPNAME } from 'src/shared/config';
28
+ import { COOPNAME } from 'src/shared/config';
29
29
 
30
30
  const desktop = useDesktopStore()
31
31
  const routes = ref<IRoute[]>([])
@@ -33,11 +33,41 @@ import { COOPNAME } from 'src/shared/config';
33
33
  const router = useRouter()
34
34
  const user = useCurrentUserStore()
35
35
 
36
+ const evaluateCondition = (condition: string, context: Record<string, any>): boolean => {
37
+ try {
38
+ const func = new Function(...Object.keys(context), `return ${condition};`);
39
+ return func(...Object.values(context));
40
+ } catch (error) {
41
+ console.error('Error evaluating condition:', error);
42
+ return false;
43
+ }
44
+ };
45
+
36
46
  const init = () => {
47
+ const isCoop = user.userAccount?.type === 'organization' &&
48
+ user.userAccount?.private_data &&
49
+ 'type' in user.userAccount.private_data &&
50
+ user.userAccount.private_data.type === 'coop';
51
+
37
52
  const userRole = user.userAccount?.role || 'user';
53
+
54
+ const context = {
55
+ isCoop,
56
+ userRole,
57
+ userAccount: user.userAccount,
58
+ coopname: COOPNAME,
59
+ // любые другие свойства, которые нужно использовать в условиях
60
+ };
61
+
38
62
  routes.value = (desktop.getSecondLevel(route) as unknown as IRoute[]).filter(
39
- (route) => route.meta?.roles?.includes(userRole) || route.meta?.roles?.length === 0
40
- );
63
+ (route) => {
64
+ const rolesMatch = route.meta?.roles?.includes(userRole) || route.meta?.roles?.length === 0;
65
+ const conditionMatch = route.meta?.conditions
66
+ ? evaluateCondition(route.meta.conditions, context)
67
+ : true; // Если условия нет, пропускаем проверку
68
+ return rolesMatch && conditionMatch;
69
+ }
70
+ );
41
71
  }
42
72
 
43
73
  // Функция проверки активного маршрута
@@ -9,7 +9,7 @@ q-btn-dropdown(flat :size="isMobile ? 'sm' : 'md'" :dense="isMobile" stretch ico
9
9
  q-icon(name="fa-solid fa-wrench").q-mr-sm
10
10
  span.font10px НАСТРОЙКИ ПАЙЩИКА
11
11
 
12
- q-item(v-if="loggedIn && isChairman" flat clickable v-close-popup @click="open('members')")
12
+ q-item(v-if="loggedIn && (isChairman || isMember)" flat clickable v-close-popup @click="open('members')")
13
13
  q-item-section
14
14
  q-item-label
15
15
  q-icon(name="fa-solid fa-hammer").q-mr-sm