saby-customizer 0.0.0-pre.19 → 0.0.0-pre.20
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/features/git-branch.js +282 -144
- package/lib/database.js +4 -1
- package/lib/saby-lib/cloud-statistic.js +1 -0
- package/lib/saby-lib/edo.js +13 -1
- package/lib/saby-lib/right-sidebar.js +7 -3
- package/package.json +1 -1
package/features/git-branch.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { oom } from '@notml/core'
|
|
2
|
-
import { keysMapping, rightSidebar, PopupDialog, getListOfOpenCards, snackbar, context } from 'saby-customizer/lib.js'
|
|
2
|
+
import { keysMapping, rightSidebar, PopupDialog, getListOfOpenCards, snackbar, context, db } from 'saby-customizer/lib.js'
|
|
3
3
|
import { octicons } from 'saby-customizer/octicons.js'
|
|
4
4
|
|
|
5
5
|
|
|
@@ -78,7 +78,8 @@ class GitBranchCard extends oom.extends(HTMLElement) {
|
|
|
78
78
|
fontSize: '14px',
|
|
79
79
|
whiteSpace: 'nowrap',
|
|
80
80
|
overflow: 'hidden',
|
|
81
|
-
textOverflow: 'ellipsis'
|
|
81
|
+
textOverflow: 'ellipsis',
|
|
82
|
+
flexGrow: '1'
|
|
82
83
|
},
|
|
83
84
|
'.description-textarea': {
|
|
84
85
|
width: '100%'
|
|
@@ -104,130 +105,196 @@ class GitBranchCard extends oom.extends(HTMLElement) {
|
|
|
104
105
|
return String(Math.min(Math.max(1, rows), 5))
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
onclick: () => this.editDescription()
|
|
126
|
-
}).dom
|
|
127
|
-
|
|
128
|
-
description = oom.span({
|
|
129
|
-
class: 'description',
|
|
130
|
-
title: this.options.data.description,
|
|
131
|
-
onclick: () => this.editDescription()
|
|
132
|
-
}, this.options.data.description).dom
|
|
133
|
-
|
|
134
|
-
/** @type {HTMLTextAreaElement} */// @ts-ignore
|
|
135
|
-
descriptionTextarea = oom.mwcTextarea({
|
|
136
|
-
class: 'description-textarea hide',
|
|
137
|
-
rows: GitBranchCard.maxRows(this.options.data.description),
|
|
138
|
-
label: 'Описание для git commit',
|
|
139
|
-
value: this.options.data.description,
|
|
140
|
-
oninput: () => {
|
|
141
|
-
this.descriptionTextarea.setAttribute('rows', GitBranchCard.maxRows(this.descriptionTextarea.value))
|
|
142
|
-
}
|
|
143
|
-
}).dom
|
|
108
|
+
/**
|
|
109
|
+
* @typedef GitCardData
|
|
110
|
+
* @property {string} [branchSubName] Имя ветки указанное пользователем
|
|
111
|
+
*/
|
|
112
|
+
/** @type {import('saby-customizer/lib.js').CardData & GitCardData} Данные о задаче */
|
|
113
|
+
data = {
|
|
114
|
+
id: this.options.data.id,
|
|
115
|
+
number: this.options.data.number,
|
|
116
|
+
branchSubName: this.options.data.branchSubName || this.options.data.number,
|
|
117
|
+
date: this.options.data.date,
|
|
118
|
+
name: this.options.data.name,
|
|
119
|
+
uuid: this.options.data.uuid,
|
|
120
|
+
url: this.options.data.url,
|
|
121
|
+
author: this.options.data.author,
|
|
122
|
+
milestones: this.options.data.milestones,
|
|
123
|
+
version: this.options.data.version,
|
|
124
|
+
description: this.options.data.description
|
|
125
|
+
}
|
|
144
126
|
|
|
145
|
-
|
|
146
|
-
|
|
127
|
+
elements = {
|
|
128
|
+
/** @type {HTMLSpanElement} */
|
|
129
|
+
cardTitle: oom.span(this.branchTitle, { title: this.branchTitle }).dom,
|
|
130
|
+
/** @type {import('@material/mwc-icon-button').IconButton} */// @ts-ignore
|
|
131
|
+
copyLinkButton: oom.mwcIconButton({
|
|
132
|
+
title: 'Скопировать ссылку',
|
|
133
|
+
class: 'icon_18',
|
|
134
|
+
innerHTML: octicons.link.toSVG({ width: 18 }),
|
|
135
|
+
onclick: () => this.copyLink()
|
|
136
|
+
}).dom,
|
|
137
|
+
/** @type {import('@material/mwc-icon-button').IconButton} */// @ts-ignore
|
|
138
|
+
descriptionEdit: oom.mwcIconButton({
|
|
139
|
+
title: 'Редактировать описание для git commit',
|
|
140
|
+
class: 'icon_18',
|
|
141
|
+
innerHTML: octicons.pencil.toSVG({ width: 18 }),
|
|
142
|
+
onclick: () => this.editDescription()
|
|
143
|
+
}).dom,
|
|
144
|
+
/** @type {HTMLSpanElement} */
|
|
145
|
+
description: oom.span({
|
|
146
|
+
class: 'description',
|
|
147
|
+
title: this.data.description,
|
|
148
|
+
onclick: () => this.editDescription()
|
|
149
|
+
}, this.data.description).dom,
|
|
150
|
+
/** @type {import('@material/mwc-textarea').TextArea} */// @ts-ignore
|
|
151
|
+
descriptionTextarea: oom.mwcTextarea({
|
|
152
|
+
class: 'description-textarea hide',
|
|
153
|
+
rows: GitBranchCard.maxRows(this.data.description),
|
|
154
|
+
label: 'Описание для git commit',
|
|
155
|
+
value: this.data.description,
|
|
156
|
+
oninput: () => this.oninputDescription()
|
|
157
|
+
}).dom,
|
|
158
|
+
/** @type {import('@material/mwc-menu').Menu} */// @ts-ignore
|
|
159
|
+
versions: this.data.milestones.reduce((mwcMenu, item) => {
|
|
160
|
+
return mwcMenu(oom.mwcListItem(item))
|
|
161
|
+
}, oom.mwcMenu({ fixed: true, activatable: true })).dom,
|
|
162
|
+
/** @type {HTMLDivElement} */// @ts-ignore
|
|
163
|
+
branchButton: oom.div({
|
|
164
|
+
class: 'version-button',
|
|
165
|
+
onclick: () => { this.elements.versions.open = true }
|
|
166
|
+
}, this.data.version).dom,
|
|
167
|
+
/** @type {HTMLSpanElement} */
|
|
168
|
+
branchNamePart: oom.span({
|
|
169
|
+
class: 'branch-part'
|
|
170
|
+
}, `/${this.branchType}/***/`).dom,
|
|
171
|
+
/** @type {HTMLSpanElement} */
|
|
172
|
+
branchSubName: oom.span({
|
|
173
|
+
title: this.data.branchSubName,
|
|
174
|
+
class: 'sub-name-button',
|
|
175
|
+
onclick: () => this.editBranchSubName()
|
|
176
|
+
}, this.data.branchSubName).dom,
|
|
177
|
+
/** @type {import('@material/mwc-textfield').TextField} */// @ts-ignore
|
|
178
|
+
branchSubNameTextfield: oom.mwcTextfield({
|
|
179
|
+
class: 'branch-sub-name hide',
|
|
180
|
+
value: this.data.branchSubName,
|
|
181
|
+
placeholder: this.data.branchSubName,
|
|
182
|
+
pattern: '^\\w+[\\w()-]*$',
|
|
183
|
+
validationmessage: 'Латинские буквы, цифры и _()-',
|
|
184
|
+
onblur: event => this.saveBranchSubName(event)
|
|
185
|
+
}).dom,
|
|
186
|
+
/** @type {import('@material/mwc-icon-button').IconButton} */// @ts-ignore
|
|
187
|
+
copyBranchButton: oom.mwcIconButton({
|
|
188
|
+
title: 'Скопировать имя ветки',
|
|
189
|
+
class: 'primary-action',
|
|
190
|
+
innerHTML: octicons['git-branch'].toSVG({ width: 24 }),
|
|
191
|
+
onclick: () => this.copyBranchName().catch(console.error)
|
|
192
|
+
}).dom,
|
|
193
|
+
/** @type {import('@material/mwc-icon-button').IconButton} */// @ts-ignore
|
|
194
|
+
copyDescriptionButton: oom.mwcIconButton({
|
|
195
|
+
title: 'Скопировать описание',
|
|
196
|
+
innerHTML: octicons.copy.toSVG({ width: 24 }),
|
|
197
|
+
onclick: () => this.copyDescription().catch(console.error)
|
|
198
|
+
}).dom
|
|
199
|
+
}
|
|
147
200
|
|
|
148
|
-
|
|
149
|
-
|
|
201
|
+
/** @returns {string} Заголовок для описания задачи */
|
|
202
|
+
get branchTitle() {
|
|
203
|
+
const { name } = this.data
|
|
204
|
+
const docNumber = ' № ' + this.data.number
|
|
205
|
+
const version = ' веха ' + this.version
|
|
206
|
+
const date = ' от ' + this.data.date
|
|
207
|
+
const author = ' ' + this.data.author
|
|
150
208
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
this.
|
|
167
|
-
this.
|
|
168
|
-
this.
|
|
169
|
-
this.branchSubNameTextfield.select()
|
|
170
|
-
}
|
|
171
|
-
}, this.options.data.number).dom
|
|
172
|
-
|
|
173
|
-
/** @type {import('@material/mwc-textfield').TextField} */// @ts-ignore
|
|
174
|
-
branchSubNameTextfield = oom.mwcTextfield({
|
|
175
|
-
class: 'branch-sub-name hide',
|
|
176
|
-
value: this.options.data.number,
|
|
177
|
-
placeholder: this.options.data.number,
|
|
178
|
-
pattern: '^\\w+$',
|
|
179
|
-
validationmessage: 'Латинские буквы и цифры',
|
|
180
|
-
onblur: (/** @type {{target:import('@material/mwc-textfield').TextField}} */{ target }) => {
|
|
181
|
-
if (target.checkValidity()) {
|
|
182
|
-
this.branchSubName.textContent = target.value || this.options.data.number
|
|
183
|
-
this.branchSubName.title = this.branchSubName.textContent
|
|
184
|
-
this.branchSubName.classList.toggle('hide')
|
|
185
|
-
this.branchSubNameTextfield.classList.toggle('hide')
|
|
186
|
-
}
|
|
209
|
+
return name + docNumber + version + date + author
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** @returns {string} Версия задачи (веха), выбранная пользователем */
|
|
213
|
+
get version() {
|
|
214
|
+
return this.data.version
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Обновление выбранной версии и обновление карточки задачи
|
|
219
|
+
*
|
|
220
|
+
* @param {string} value Версия
|
|
221
|
+
*/
|
|
222
|
+
set version(value) {
|
|
223
|
+
if (this.data.milestones && this.data.milestones.includes(value)) {
|
|
224
|
+
this.data.version = value
|
|
225
|
+
this.elements.branchButton.textContent = this.data.version
|
|
226
|
+
this.elements.cardTitle.textContent = this.branchTitle
|
|
187
227
|
}
|
|
188
|
-
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** @returns {string} Часть имени ветки, зависящая от регламента задачи */
|
|
231
|
+
get branchType() {
|
|
232
|
+
return this.data.name === 'Ошибка' ? 'bugfix' : 'feature'
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** @returns {string} Часть имени ветки, определяемая пользователем */
|
|
236
|
+
get branchSubName() {
|
|
237
|
+
return this.data.branchSubName
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Обновление доп. имени ветки и обновление карточки задачи
|
|
242
|
+
*
|
|
243
|
+
* @param {string} value Доп. имя ветки
|
|
244
|
+
*/
|
|
245
|
+
set branchSubName(value) {
|
|
246
|
+
this.data.branchSubName = value || this.data.number
|
|
247
|
+
this.elements.branchSubName.textContent = this.data.branchSubName
|
|
248
|
+
this.elements.branchSubName.title = this.data.branchSubName
|
|
249
|
+
this.elements.branchSubNameTextfield.value = this.data.branchSubName
|
|
250
|
+
}
|
|
189
251
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
onclick: () => this.copyBranchName().catch(console.error)
|
|
195
|
-
}).dom
|
|
252
|
+
/** @returns {string} Краткое описание задачи */
|
|
253
|
+
get description() {
|
|
254
|
+
return this.data.description
|
|
255
|
+
}
|
|
196
256
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
257
|
+
/**
|
|
258
|
+
* Обновление краткого описания и карточки задачи
|
|
259
|
+
*
|
|
260
|
+
* @param {string} value Доп. имя ветки
|
|
261
|
+
*/
|
|
262
|
+
set description(value) {
|
|
263
|
+
this.data.description = value || ''
|
|
264
|
+
this.elements.description.title = this.data.description
|
|
265
|
+
this.elements.description.textContent = this.data.description
|
|
266
|
+
if (this.elements.descriptionTextarea.value !== this.data.description) {
|
|
267
|
+
this.elements.descriptionTextarea.value = this.data.description
|
|
268
|
+
}
|
|
269
|
+
oom(this.elements.descriptionTextarea, { rows: GitBranchCard.maxRows(this.data.description) })
|
|
270
|
+
}
|
|
202
271
|
|
|
203
272
|
template = () => {
|
|
204
|
-
this.versions.anchor = this.branchButton
|
|
205
|
-
this.versions.addEventListener('selected', (event) => {
|
|
206
|
-
this.version = this.milestones[event.detail.index]
|
|
207
|
-
this.cardTitle.textContent = this.getTitle()
|
|
208
|
-
this.branchButton.textContent = this.version
|
|
273
|
+
this.elements.versions.anchor = this.elements.branchButton
|
|
274
|
+
this.elements.versions.addEventListener('selected', (/** @type {CustomEvent<import('@material/mwc-list/mwc-list-foundation').ActionDetail>} */event) => {
|
|
275
|
+
this.version = this.data.milestones[event.detail.index]
|
|
209
276
|
})
|
|
210
277
|
|
|
211
278
|
this.updateBranchNamePart().catch(console.error)
|
|
212
279
|
|
|
213
280
|
return oom.div({ class: 'mdc-card' }, oom
|
|
214
|
-
.div({ class: 'title' }, this.cardTitle)
|
|
281
|
+
.div({ class: 'title' }, this.elements.cardTitle)
|
|
215
282
|
.div(oom
|
|
216
|
-
.a({ class: 'link' }, this.url, {
|
|
283
|
+
.a({ class: 'link' }, this.data.url, {
|
|
217
284
|
target: '_blank',
|
|
218
|
-
href: this.url
|
|
219
|
-
}), this.copyLinkButton)
|
|
285
|
+
href: this.data.url
|
|
286
|
+
}), this.elements.copyLinkButton)
|
|
220
287
|
.div({
|
|
221
288
|
class: 'description-line'
|
|
222
|
-
}, this.descriptionEdit, this.description, this.descriptionTextarea)
|
|
289
|
+
}, this.elements.descriptionEdit, this.elements.description, this.elements.descriptionTextarea)
|
|
223
290
|
.div({ class: 'branch-line' }, oom
|
|
224
291
|
.div({ class: 'branch' },
|
|
225
|
-
this.branchButton,
|
|
226
|
-
this.versions,
|
|
227
|
-
this.branchNamePart,
|
|
228
|
-
this.branchSubName,
|
|
229
|
-
this.branchSubNameTextfield)
|
|
230
|
-
.div({ class: 'actions' }, this.copyBranchButton, this.copyDescriptionButton)
|
|
292
|
+
this.elements.branchButton,
|
|
293
|
+
this.elements.versions,
|
|
294
|
+
this.elements.branchNamePart,
|
|
295
|
+
this.elements.branchSubName,
|
|
296
|
+
this.elements.branchSubNameTextfield)
|
|
297
|
+
.div({ class: 'actions' }, this.elements.copyBranchButton, this.elements.copyDescriptionButton)
|
|
231
298
|
)
|
|
232
299
|
)
|
|
233
300
|
}
|
|
@@ -236,64 +303,122 @@ class GitBranchCard extends oom.extends(HTMLElement) {
|
|
|
236
303
|
async updateBranchNamePart() {
|
|
237
304
|
const userLogin = await context.userLogin
|
|
238
305
|
|
|
239
|
-
this.branchNamePart.textContent = `/${this.branchType}/${userLogin}/`
|
|
306
|
+
this.elements.branchNamePart.textContent = `/${this.branchType}/${userLogin}/`
|
|
240
307
|
}
|
|
241
308
|
|
|
242
|
-
/**
|
|
309
|
+
/** Открывает форму редактирования редактирование описания для коммита */
|
|
243
310
|
editDescription() {
|
|
244
|
-
this.descriptionEdit.classList.toggle('hide')
|
|
245
|
-
this.description.classList.toggle('hide')
|
|
246
|
-
this.descriptionTextarea.classList.toggle('hide')
|
|
247
|
-
this.descriptionTextarea.focus()
|
|
311
|
+
this.elements.descriptionEdit.classList.toggle('hide')
|
|
312
|
+
this.elements.description.classList.toggle('hide')
|
|
313
|
+
this.elements.descriptionTextarea.classList.toggle('hide')
|
|
314
|
+
this.elements.descriptionTextarea.focus()
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Обработка события при вводе текста в описание для расчета отображаемого кол-ва строк */
|
|
318
|
+
oninputDescription() {
|
|
319
|
+
this.description = this.elements.descriptionTextarea.value
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Открывает форму редактирования доп. имени ветки */
|
|
323
|
+
editBranchSubName() {
|
|
324
|
+
this.elements.branchSubName.classList.toggle('hide')
|
|
325
|
+
this.elements.branchSubNameTextfield.classList.toggle('hide')
|
|
326
|
+
this.elements.branchSubNameTextfield.focus()
|
|
327
|
+
this.elements.branchSubNameTextfield.select()
|
|
248
328
|
}
|
|
249
329
|
|
|
250
330
|
/**
|
|
251
|
-
*
|
|
331
|
+
* Сохранение данных о доп. имени ветки при потере фокуса с поля ввода
|
|
332
|
+
*
|
|
333
|
+
* @param {{target:import('@material/mwc-textfield').TextField}} event Данные о событи onblur
|
|
252
334
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return name + docNumber + version + date + author
|
|
335
|
+
saveBranchSubName({ target }) {
|
|
336
|
+
if (target.checkValidity()) {
|
|
337
|
+
this.branchSubName = target.value
|
|
338
|
+
this.elements.branchSubName.classList.toggle('hide')
|
|
339
|
+
this.elements.branchSubNameTextfield.classList.toggle('hide')
|
|
340
|
+
}
|
|
261
341
|
}
|
|
262
342
|
|
|
263
343
|
/**
|
|
344
|
+
* Получение имени ветки с учетом выбора вехи и доп. имени ветки
|
|
345
|
+
*
|
|
264
346
|
* @returns {Promise<string>} Имя ветки
|
|
265
347
|
*/
|
|
266
348
|
async getBranchName() {
|
|
267
|
-
const branchSubName = this.branchSubNameTextfield.value || this.options.data.number
|
|
268
349
|
const userLogin = await context.userLogin
|
|
269
350
|
|
|
270
|
-
return `${this.version}/${this.branchType}/${userLogin}/${branchSubName}`
|
|
351
|
+
return `${this.version}/${this.branchType}/${userLogin}/${this.branchSubName}`
|
|
271
352
|
}
|
|
272
353
|
|
|
273
354
|
/** Копирование ссылки на задачу */
|
|
274
355
|
copyLink() {
|
|
275
|
-
navigator.clipboard.writeText(this.url)
|
|
276
|
-
snackbar.show(`Скопирована ссылка: ${this.url}`)
|
|
356
|
+
navigator.clipboard.writeText(this.data.url)
|
|
357
|
+
snackbar.show(`Скопирована ссылка: ${this.data.url}`)
|
|
277
358
|
}
|
|
278
359
|
|
|
279
360
|
/** Копирование имени ветки */
|
|
280
361
|
async copyBranchName() {
|
|
281
|
-
if (this.branchSubNameTextfield.checkValidity()) {
|
|
362
|
+
if (this.elements.branchSubNameTextfield.checkValidity()) {
|
|
282
363
|
const branchName = await this.getBranchName()
|
|
283
364
|
|
|
284
365
|
navigator.clipboard.writeText(branchName)
|
|
285
366
|
snackbar.show(`Скопировано имя ветки: ${branchName}`)
|
|
367
|
+
|
|
368
|
+
await this.saveToHistory()
|
|
286
369
|
}
|
|
287
370
|
}
|
|
288
371
|
|
|
289
372
|
/** Копирование описания для git commit */
|
|
290
|
-
copyDescription() {
|
|
291
|
-
const description = this.
|
|
292
|
-
this.url + '\n' +
|
|
293
|
-
this.
|
|
373
|
+
async copyDescription() {
|
|
374
|
+
const description = this.branchTitle + '\n' +
|
|
375
|
+
this.data.url + '\n' +
|
|
376
|
+
this.description
|
|
294
377
|
|
|
295
378
|
navigator.clipboard.writeText(description)
|
|
296
379
|
snackbar.show(`Скопировано описание для git commit:\n${description}`)
|
|
380
|
+
|
|
381
|
+
await this.saveToHistory()
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Сохраняет данные в историю по карточкам для которых копировали имя ветки или описание */
|
|
385
|
+
async saveToHistory() {
|
|
386
|
+
const branchName = await this.getBranchName()
|
|
387
|
+
const gitBranchHistory = db.table('gitBranchHistory')
|
|
388
|
+
const historyOldData = await gitBranchHistory.get({
|
|
389
|
+
id: this.data.id,
|
|
390
|
+
branch: branchName
|
|
391
|
+
})
|
|
392
|
+
const historyData = {
|
|
393
|
+
id: this.data.id,
|
|
394
|
+
branch: branchName,
|
|
395
|
+
version: this.version,
|
|
396
|
+
useDate: new Date(),
|
|
397
|
+
data: this.data
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (historyOldData) {
|
|
401
|
+
await gitBranchHistory.update(historyOldData.pk, historyData)
|
|
402
|
+
} else {
|
|
403
|
+
await gitBranchHistory.add(historyData)
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** Восстановление из истории последнего сохраненного состояния карточки */
|
|
408
|
+
async restoreFromHistory() {
|
|
409
|
+
const gitBranchHistory = db.table('gitBranchHistory')
|
|
410
|
+
const historyData = await gitBranchHistory
|
|
411
|
+
.where({ id: this.options.data.id })
|
|
412
|
+
.reverse()
|
|
413
|
+
.sortBy('useDate')
|
|
414
|
+
|
|
415
|
+
if (historyData && historyData.length > 0) {
|
|
416
|
+
const [{ data: { version, branchSubName, description } }] = historyData
|
|
417
|
+
|
|
418
|
+
this.version = version
|
|
419
|
+
this.branchSubName = branchSubName
|
|
420
|
+
this.description = description
|
|
421
|
+
}
|
|
297
422
|
}
|
|
298
423
|
|
|
299
424
|
}
|
|
@@ -321,22 +446,35 @@ class GitBranchCardList extends oom.extends(HTMLElement) {
|
|
|
321
446
|
// .mwcTab({ label: 'Список задач' })
|
|
322
447
|
.mwcTab({ label: 'История задач' }))
|
|
323
448
|
|
|
324
|
-
|
|
325
|
-
names: ['Ошибка', 'Задача'],
|
|
326
|
-
hasVersion: true
|
|
327
|
-
})
|
|
328
|
-
.map(card => new GitBranchCard(card))
|
|
449
|
+
list = oom.div({ class: 'content' })
|
|
329
450
|
|
|
330
|
-
|
|
331
|
-
|
|
451
|
+
template = async () => {
|
|
452
|
+
// if (this.openTaskList.length === 0) {
|
|
453
|
+
// this.tabs({ activeindex: '1' })
|
|
454
|
+
// }
|
|
455
|
+
oom(this, this.tabs, this.list)
|
|
456
|
+
oom(this.list, oom.div({ class: 'empty' }, 'Загрузка ...'))
|
|
332
457
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
458
|
+
this.list({ innerHTML: '' }, await this.buildTaskList())
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/** @returns {Promise<HTMLElement|DocumentFragment>} Вернет готовый список задач с учетом аинхронной загрузки данных */
|
|
462
|
+
async buildTaskList() {
|
|
463
|
+
let taskTist = null
|
|
464
|
+
const openTaskList = (await getListOfOpenCards({
|
|
465
|
+
names: ['Ошибка', 'Задача'],
|
|
466
|
+
hasVersion: true
|
|
467
|
+
})).map(card => new GitBranchCard(card))
|
|
468
|
+
|
|
469
|
+
await Promise.all(openTaskList.map(card => card.restoreFromHistory()))
|
|
470
|
+
|
|
471
|
+
if (openTaskList.length > 0) {
|
|
472
|
+
taskTist = oom()(...openTaskList)
|
|
473
|
+
} else {
|
|
474
|
+
taskTist = oom.div({ class: 'empty' }, 'Открытых задач с вехой не найдено')
|
|
336
475
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}, this.openTaskListElement))
|
|
476
|
+
|
|
477
|
+
return taskTist.dom
|
|
340
478
|
}
|
|
341
479
|
|
|
342
480
|
}
|
package/lib/database.js
CHANGED
|
@@ -3,7 +3,10 @@ import { Dexie } from 'dexie'
|
|
|
3
3
|
const db = new Dexie('saby-customizer-database')
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
db.version(
|
|
6
|
+
db.version(2).stores({
|
|
7
|
+
settings: '&key',
|
|
8
|
+
gitBranchHistory: '++pk, &[id+branch], version, useDate'
|
|
9
|
+
})
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
export { db }
|
package/lib/saby-lib/edo.js
CHANGED
|
@@ -68,7 +68,16 @@ function parseRichEditorJSON(json) {
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* @typedef CardData Данные карточки документа
|
|
71
|
+
* @property {string} id Идентификатор документа
|
|
71
72
|
* @property {string} number Номер документа
|
|
73
|
+
* @property {string} date Дата создания документа
|
|
74
|
+
* @property {string} name Название регламента Задача/Ошибка и т.д.
|
|
75
|
+
* @property {string} uuid UUID документа (для открытия ссылки)
|
|
76
|
+
* @property {string} url Ссылка на документ в отдельной вкладке
|
|
77
|
+
* @property {string} author Автор документа
|
|
78
|
+
* @property {string[]} milestones Список доступных вех (версий)
|
|
79
|
+
* @property {string} version Ближайшая версия
|
|
80
|
+
* @property {string} description Краткий текст описания задачи
|
|
72
81
|
*/
|
|
73
82
|
/**
|
|
74
83
|
* @typedef OpenCardsFilter Фильтры для выборки документов
|
|
@@ -95,13 +104,16 @@ export function getListOfOpenCards(filter = {}) {
|
|
|
95
104
|
const { element } = control
|
|
96
105
|
const record = control?.options?.record
|
|
97
106
|
const data = record && {
|
|
107
|
+
id: record.get('@Документ'),
|
|
98
108
|
number: record.get('Номер'),
|
|
99
109
|
date: getStrDate(record.get('Дата')),
|
|
100
110
|
name: record.get('РП.Документ').get('Регламент').get('Название'),
|
|
101
111
|
uuid: record.get('РП.Документ').get('ИдентификаторПереписки'),
|
|
112
|
+
url: '',
|
|
102
113
|
author: record.get('ЛицоСоздал.Название') || record.get('Сотрудник.Название'),
|
|
103
114
|
milestones: [],
|
|
104
|
-
version: 'dev'
|
|
115
|
+
version: 'dev',
|
|
116
|
+
description: ''
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
if (data) {
|
|
@@ -93,7 +93,12 @@ class RightSidebarButtonsContainer extends oom.extends(HTMLElement, { global: fa
|
|
|
93
93
|
|
|
94
94
|
if (popupContainer) {
|
|
95
95
|
this.observer = new MutationObserver(() => {
|
|
96
|
-
|
|
96
|
+
let rightPanels = popupContainer.querySelectorAll('.controls-StackTemplate__rightPanel .sabyPage-MainLayout__wrapper')
|
|
97
|
+
|
|
98
|
+
if (rightPanels.length === 0) {
|
|
99
|
+
// Кнопки для всплывающий панелей в карточке открытой в отдельной вкладке
|
|
100
|
+
rightPanels = popupContainer.querySelectorAll('.controls-StackTemplate__rightPanel .sabyPage-widgets__wrapper')
|
|
101
|
+
}
|
|
97
102
|
|
|
98
103
|
rightPanels.forEach(panel => {
|
|
99
104
|
const rightSidebar = panel.querySelector('saby-customizer-right-sidebar')
|
|
@@ -103,9 +108,8 @@ class RightSidebarButtonsContainer extends oom.extends(HTMLElement, { global: fa
|
|
|
103
108
|
}
|
|
104
109
|
})
|
|
105
110
|
})
|
|
111
|
+
this.observer.observe(popupContainer, { childList: true })
|
|
106
112
|
}
|
|
107
|
-
|
|
108
|
-
this.observer.observe(popupContainer, { childList: true })
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
template = () => {
|