saby-customizer 0.0.0-pre.17 → 0.0.0-pre.21

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.
@@ -1,5 +1,5 @@
1
1
  import { oom } from '@notml/core'
2
- import { PopupDialog, keysMapping, 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
 
@@ -9,9 +9,12 @@ class GitBranchCard extends oom.extends(HTMLElement) {
9
9
  static tagName = 'sc-git-branch-сard'
10
10
  static style = oom.style({
11
11
  'display': 'flex',
12
- 'padding': '12px',
12
+ 'padding': '12px 12px 0',
13
13
  'width': '600px',
14
14
  'background': 'var(--mdc-theme-background)',
15
+ 'sc-git-branch-сard:last-child': {
16
+ paddingBottom: '12px'
17
+ },
15
18
  '.mdc-card': {
16
19
  padding: '12px',
17
20
  minWidth: '0',
@@ -75,7 +78,8 @@ class GitBranchCard extends oom.extends(HTMLElement) {
75
78
  fontSize: '14px',
76
79
  whiteSpace: 'nowrap',
77
80
  overflow: 'hidden',
78
- textOverflow: 'ellipsis'
81
+ textOverflow: 'ellipsis',
82
+ flexGrow: '1'
79
83
  },
80
84
  '.description-textarea': {
81
85
  width: '100%'
@@ -101,130 +105,196 @@ class GitBranchCard extends oom.extends(HTMLElement) {
101
105
  return String(Math.min(Math.max(1, rows), 5))
102
106
  }
103
107
 
104
- url = this.options.data.url
105
- version = this.options.data.version
106
- milestones = this.options.data.milestones
107
- branchType = this.options.data.name === 'Ошибка' ? 'bugfix' : 'feature'
108
-
109
- cardTitle = oom.span(this.getTitle(), { title: this.getTitle() }).dom
110
-
111
- copyLinkButton = oom.mwcIconButton({
112
- title: 'Скопировать ссылку',
113
- class: 'icon_18',
114
- innerHTML: octicons.link.toSVG(),
115
- onclick: () => this.copyLink()
116
- }).dom
117
-
118
- descriptionEdit = oom.mwcIconButton({
119
- title: 'Редактировать описание для git commit',
120
- class: 'icon_18',
121
- innerHTML: octicons.pencil.toSVG(),
122
- onclick: () => this.editDescription()
123
- }).dom
124
-
125
- description = oom.span({
126
- class: 'description',
127
- title: this.options.data.description,
128
- onclick: () => this.editDescription()
129
- }, this.options.data.description).dom
130
-
131
- /** @type {HTMLTextAreaElement} */// @ts-ignore
132
- descriptionTextarea = oom.mwcTextarea({
133
- class: 'description-textarea hide',
134
- rows: GitBranchCard.maxRows(this.options.data.description),
135
- label: 'Описание для git commit',
136
- value: this.options.data.description,
137
- oninput: () => {
138
- this.descriptionTextarea.setAttribute('rows', GitBranchCard.maxRows(this.descriptionTextarea.value))
139
- }
140
- }).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
+ }
126
+
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
+ }
141
200
 
142
- versions = this.milestones.reduce((mwcMenu, item) => {
143
- mwcMenu(oom.mwcListItem(item))
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
144
208
 
145
- return mwcMenu
146
- }, oom.mwcMenu({ fixed: true, activatable: true })).dom
209
+ return name + docNumber + version + date + author
210
+ }
147
211
 
148
- branchButton = oom.div({
149
- class: 'version-button',
150
- onclick: () => {
151
- this.versions.open = true
152
- }
153
- }, this.version).dom
154
-
155
- branchNamePart = oom.span({
156
- class: 'branch-part'
157
- }, `/${this.branchType}/***/`).dom
158
-
159
- branchSubName = oom.span({
160
- title: this.options.data.number,
161
- class: 'sub-name-button',
162
- onclick: () => {
163
- this.branchSubName.classList.toggle('hide')
164
- this.branchSubNameTextfield.classList.toggle('hide')
165
- this.branchSubNameTextfield.focus()
166
- this.branchSubNameTextfield.select()
167
- }
168
- }, this.options.data.number).dom
169
-
170
- /** @type {import('@material/mwc-textfield').TextField} */// @ts-ignore
171
- branchSubNameTextfield = oom.mwcTextfield({
172
- class: 'branch-sub-name hide',
173
- value: this.options.data.number,
174
- placeholder: this.options.data.number,
175
- pattern: '^\\w+$',
176
- validationmessage: 'Латинские буквы и цифры',
177
- onblur: (/** @type {{target:import('@material/mwc-textfield').TextField}} */{ target }) => {
178
- if (target.checkValidity()) {
179
- this.branchSubName.textContent = target.value || this.options.data.number
180
- this.branchSubName.title = this.branchSubName.textContent
181
- this.branchSubName.classList.toggle('hide')
182
- this.branchSubNameTextfield.classList.toggle('hide')
183
- }
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
184
227
  }
185
- }).dom
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
+ }
186
251
 
187
- copyBranchButton = oom.mwcIconButton({
188
- title: 'Скопировать имя ветки',
189
- class: 'primary-action',
190
- innerHTML: octicons['git-branch'].toSVG(),
191
- onclick: () => this.copyBranchName().catch(console.error)
192
- }).dom
252
+ /** @returns {string} Краткое описание задачи */
253
+ get description() {
254
+ return this.data.description
255
+ }
193
256
 
194
- copyDescriptionButton = oom.mwcIconButton({
195
- title: 'Скопировать описание',
196
- innerHTML: octicons.copy.toSVG(),
197
- onclick: () => this.copyDescription()
198
- }).dom
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
+ }
199
271
 
200
272
  template = () => {
201
- this.versions.anchor = this.branchButton
202
- this.versions.addEventListener('selected', (event) => {
203
- this.version = this.milestones[event.detail.index]
204
- this.cardTitle.textContent = this.getTitle()
205
- 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]
206
276
  })
207
277
 
208
278
  this.updateBranchNamePart().catch(console.error)
209
279
 
210
280
  return oom.div({ class: 'mdc-card' }, oom
211
- .div({ class: 'title' }, this.cardTitle)
281
+ .div({ class: 'title' }, this.elements.cardTitle)
212
282
  .div(oom
213
- .a({ class: 'link' }, this.url, {
283
+ .a({ class: 'link' }, this.data.url, {
214
284
  target: '_blank',
215
- href: this.url
216
- }), this.copyLinkButton)
285
+ href: this.data.url
286
+ }), this.elements.copyLinkButton)
217
287
  .div({
218
288
  class: 'description-line'
219
- }, this.descriptionEdit, this.description, this.descriptionTextarea)
289
+ }, this.elements.descriptionEdit, this.elements.description, this.elements.descriptionTextarea)
220
290
  .div({ class: 'branch-line' }, oom
221
291
  .div({ class: 'branch' },
222
- this.branchButton,
223
- this.versions,
224
- this.branchNamePart,
225
- this.branchSubName,
226
- this.branchSubNameTextfield)
227
- .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)
228
298
  )
229
299
  )
230
300
  }
@@ -233,64 +303,122 @@ class GitBranchCard extends oom.extends(HTMLElement) {
233
303
  async updateBranchNamePart() {
234
304
  const userLogin = await context.userLogin
235
305
 
236
- this.branchNamePart.textContent = `/${this.branchType}/${userLogin}/`
306
+ this.elements.branchNamePart.textContent = `/${this.branchType}/${userLogin}/`
237
307
  }
238
308
 
239
- /** Запускает редактирование описания для коммита */
309
+ /** Открывает форму редактирования редактирование описания для коммита */
240
310
  editDescription() {
241
- this.descriptionEdit.classList.toggle('hide')
242
- this.description.classList.toggle('hide')
243
- this.descriptionTextarea.classList.toggle('hide')
244
- 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()
245
328
  }
246
329
 
247
330
  /**
248
- * @returns {string} Заголовок
331
+ * Сохранение данных о доп. имени ветки при потере фокуса с поля ввода
332
+ *
333
+ * @param {{target:import('@material/mwc-textfield').TextField}} event Данные о событи onblur
249
334
  */
250
- getTitle() {
251
- const { name } = this.options.data
252
- const docNumber = ' № ' + this.options.data.number
253
- const version = ' веха ' + this.version
254
- const date = ' от ' + this.options.data.date
255
- const author = ' ' + this.options.data.author
256
-
257
- 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
+ }
258
341
  }
259
342
 
260
343
  /**
344
+ * Получение имени ветки с учетом выбора вехи и доп. имени ветки
345
+ *
261
346
  * @returns {Promise<string>} Имя ветки
262
347
  */
263
348
  async getBranchName() {
264
- const branchSubName = this.branchSubNameTextfield.value || this.options.data.number
265
349
  const userLogin = await context.userLogin
266
350
 
267
- return `${this.version}/${this.branchType}/${userLogin}/${branchSubName}`
351
+ return `${this.version}/${this.branchType}/${userLogin}/${this.branchSubName}`
268
352
  }
269
353
 
270
354
  /** Копирование ссылки на задачу */
271
355
  copyLink() {
272
- navigator.clipboard.writeText(this.url)
273
- snackbar.show(`Скопирована ссылка: ${this.url}`)
356
+ navigator.clipboard.writeText(this.data.url)
357
+ snackbar.show(`Скопирована ссылка: ${this.data.url}`)
274
358
  }
275
359
 
276
360
  /** Копирование имени ветки */
277
361
  async copyBranchName() {
278
- if (this.branchSubNameTextfield.checkValidity()) {
362
+ if (this.elements.branchSubNameTextfield.checkValidity()) {
279
363
  const branchName = await this.getBranchName()
280
364
 
281
365
  navigator.clipboard.writeText(branchName)
282
366
  snackbar.show(`Скопировано имя ветки: ${branchName}`)
367
+
368
+ await this.saveToHistory()
283
369
  }
284
370
  }
285
371
 
286
372
  /** Копирование описания для git commit */
287
- copyDescription() {
288
- const description = this.getTitle() + '\n' +
289
- this.url + '\n' +
290
- this.descriptionTextarea.value
373
+ async copyDescription() {
374
+ const description = this.branchTitle + '\n' +
375
+ this.data.url + '\n' +
376
+ this.description
291
377
 
292
378
  navigator.clipboard.writeText(description)
293
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
+ }
294
422
  }
295
423
 
296
424
  }
@@ -305,29 +433,48 @@ class GitBranchCardList extends oom.extends(HTMLElement) {
305
433
  '.empty': {
306
434
  padding: '100px',
307
435
  textAlign: 'center'
436
+ },
437
+ '.content': {
438
+ overflow: 'auto',
439
+ maxHeight: 'calc(var(--mdc-dialog-max-height) - 100px)'
308
440
  }
309
441
  })
310
442
 
311
443
  tabs = oom
312
444
  .mwcTabBar(oom
313
445
  .mwcTab({ label: 'Открытые задачи' })
314
- .mwcTab({ label: 'Список задач' })
446
+ // .mwcTab({ label: 'Список задач' })
315
447
  .mwcTab({ label: 'История задач' }))
316
448
 
317
- openTaskList = getListOfOpenCards({
318
- names: ['Ошибка', 'Задача'],
319
- hasVersion: true
320
- })
321
- .map(card => new GitBranchCard(card))
449
+ list = oom.div({ class: 'content' })
322
450
 
323
- openTaskListElement = (this.openTaskList.length > 0 && oom()(...this.openTaskList)) || oom
324
- .div({ class: 'empty' }, 'Открытых задач с вехой не найдено')
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' }, 'Загрузка ...'))
325
457
 
326
- template = () => {
327
- if (this.openTaskList.length === 0) {
328
- this.tabs({ activeindex: '1' })
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' }, 'Открытых задач с вехой не найдено')
329
475
  }
330
- oom(this, this.tabs, this.openTaskListElement)
476
+
477
+ return taskTist.dom
331
478
  }
332
479
 
333
480
  }
@@ -340,3 +487,9 @@ keysMapping['alt-KeyB'] = () => PopupDialog.toggle({
340
487
  title: 'Ветки для Git',
341
488
  Element: GitBranchCardList
342
489
  })
490
+
491
+ rightSidebar.addButton({
492
+ title: 'Ветки для Git',
493
+ iconSVG: octicons['git-branch'].toSVG({ width: 24 }),
494
+ onclick: keysMapping['alt-KeyB']
495
+ })
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(1).stores({ settings: '&key' })
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/layout.js CHANGED
@@ -14,6 +14,9 @@ class SabyCustomizerLayout extends oom.extends(HTMLElement) {
14
14
  inner = oom.section(...this.options.inner).dom
15
15
 
16
16
  template = () => {
17
+ // Атрибуты для игнорирования контейнера платформой wasaby
18
+ this.setAttribute('data-vdomignore', 'true')
19
+ this.setAttribute('contenteditable', 'true')
17
20
  // Предзагрузка стилей material внутри теневого DOM
18
21
  this.style.display = 'none'
19
22
  this.externalCSS.onload = () => { this.style.display = '' }
@@ -46,7 +46,8 @@ export class PopupDialog extends oom.extends(HTMLElement, PopupDialogDefaults) {
46
46
  },
47
47
  'mwc-dialog': {
48
48
  '--mdc-dialog-z-index': '10000',
49
- '--mdc-dialog-max-width': '700px'
49
+ '--mdc-dialog-max-width': '700px',
50
+ '--mdc-dialog-max-height': '600px'
50
51
  },
51
52
  'header': {
52
53
  margin: '-20px -24px 0px -24px',
@@ -60,7 +61,9 @@ export class PopupDialog extends oom.extends(HTMLElement, PopupDialogDefaults) {
60
61
  overflow: 'hidden'
61
62
  },
62
63
  'main': {
63
- margin: '0px -24px -20px -24px'
64
+ margin: '0px -24px -20px -24px',
65
+ overflow: 'auto',
66
+ maxHeight: 'calc(var(--mdc-dialog-max-height) - 52px)'
64
67
  }
65
68
  })
66
69
 
@@ -1,2 +1,3 @@
1
1
  // Собрать стату по использованию фич кастомайзера
2
2
  // https://online.sbis.ru/news/4a005fd5-c99b-4e8d-a78b-eeb67b78d892
3
+ // https://git.sbis.ru/contragents/online/-/blob/rc-22.1200/client/ContractorCommon/_statisticCollection/Helper.ts
@@ -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) {
@@ -152,7 +164,7 @@ export function getListOfOpenCards(filter = {}) {
152
164
  data.description = 'Описание задачи не заполнено'
153
165
  }
154
166
 
155
- cards.push({ element, data })
167
+ cards.unshift({ element, data })
156
168
  }
157
169
  }
158
170
  }
@@ -0,0 +1,164 @@
1
+ import { oom } from '@notml/core'
2
+
3
+ const { MutationObserver } = window
4
+
5
+
6
+ /** Класс контейнера для расширения правой панели сайта дополнительными кнопками */
7
+ class RightSidebarButtonsContainer extends oom.extends(HTMLElement, { global: false }) {
8
+
9
+ static tagName = 'saby-customizer-right-sidebar'
10
+ static style = oom.style({
11
+ 'saby-customizer-right-sidebar': {
12
+ marginBottom: '12px'
13
+ },
14
+ '.button': {
15
+ color: 'var(--secondary_icon-color)',
16
+ fill: 'var(--secondary_icon-color)',
17
+ cursor: 'pointer',
18
+ height: '32px',
19
+ width: '32px',
20
+ display: 'flex',
21
+ justifyContent: 'center',
22
+ alignItems: 'center'
23
+ },
24
+ '.button:hover': {
25
+ color: 'var(--link_hover_text-color)',
26
+ fill: 'var(--link_hover_text-color)',
27
+ borderColor: ' var(--border-color_hover_button_toolButton)',
28
+ background: 'var(--background-color_hover_button_toolButton)',
29
+ borderRadius: 'var(--border-radius_button_toolButton)',
30
+ borderWidth: 'var(--border-thickness_button)'
31
+ }
32
+ })
33
+
34
+ /**
35
+ * @typedef ButtonOptions
36
+ * @property {string} title Всплывающая подсказка на кнопке
37
+ * @property {string} iconSVG Верстка иконки в формате SVG
38
+ * @property {Function} onclick Обработчик клика на иконку
39
+ */
40
+ /** @type {ButtonOptions[]} */
41
+ static buttons = []
42
+
43
+ /** @type {Set<RightSidebarButtonsContainer>} */
44
+ static containers = new Set()
45
+
46
+ /** @type {RightSidebarButtonsContainer} */
47
+ static globalContainer = null
48
+
49
+ /** @type {MutationObserver} */
50
+ static observer = null
51
+
52
+ /**
53
+ * Регистрирует новую общую кнопку в правой панели сайта
54
+ *
55
+ * @param {ButtonOptions} options Опции кнопки
56
+ */
57
+ static addButton(options) {
58
+ this.buttons.push(options)
59
+
60
+ this.containers.forEach(container => container.addButton(options))
61
+
62
+ if (!RightSidebarButtonsContainer.globalContainer) {
63
+ this.addGlobalContainer()
64
+ }
65
+ if (!this.observer) {
66
+ this.registerTaskPanelWatcher()
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Добавляет в вертску сайта глобальный контейнер в правой панели для добавления кнопок
72
+ */
73
+ static addGlobalContainer() {
74
+ const sabyPageRightPanel = document.querySelector('.sabyPage-MainLayout__rightPanel .sabyPage-MainLayout__wrapper')
75
+
76
+ if (sabyPageRightPanel) {
77
+ RightSidebarButtonsContainer.globalContainer = new RightSidebarButtonsContainer({ global: true })
78
+ sabyPageRightPanel.prepend(RightSidebarButtonsContainer.globalContainer)
79
+ } else {
80
+ // Глобальные кнопки в карточке открытой в отдельной вкладке
81
+ const cardRightPanel = document.querySelector('.controls-StackTemplate__rightPanel .sabyPage-widgets__wrapper')
82
+
83
+ if (cardRightPanel) {
84
+ RightSidebarButtonsContainer.globalContainer = new RightSidebarButtonsContainer({ global: true })
85
+ cardRightPanel.prepend(RightSidebarButtonsContainer.globalContainer)
86
+ }
87
+ }
88
+ }
89
+
90
+ /** Регистрирует обработчик для поиска открытых задач и добавления в них правой панели */
91
+ static registerTaskPanelWatcher() {
92
+ const popupContainer = document.getElementById('popup')
93
+
94
+ if (popupContainer) {
95
+ this.observer = new MutationObserver(() => {
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
+ }
102
+
103
+ rightPanels.forEach(panel => {
104
+ const rightSidebar = panel.querySelector('saby-customizer-right-sidebar')
105
+
106
+ if (!rightSidebar) {
107
+ panel.prepend(new RightSidebarButtonsContainer())
108
+ }
109
+ })
110
+ })
111
+ this.observer.observe(popupContainer, { childList: true })
112
+ }
113
+ }
114
+
115
+ template = () => {
116
+ // Атрибуты для игнорирования контейнера платформой wasaby
117
+ this.setAttribute('data-vdomignore', 'true')
118
+ this.setAttribute('contenteditable', 'true')
119
+ }
120
+
121
+ /** Будем запоминать все контейнеры для синхронизации кнопок */
122
+ connectedCallback() {
123
+ RightSidebarButtonsContainer.containers.add(this)
124
+ RightSidebarButtonsContainer.buttons.forEach(options => this.addButton(options))
125
+ }
126
+
127
+ /** Очищаем удаленные из DOM контейнеры */
128
+ disconnectedCallback() {
129
+ if (this.options.global) {
130
+ RightSidebarButtonsContainer.globalContainer = null
131
+ RightSidebarButtonsContainer.addGlobalContainer()
132
+ }
133
+ RightSidebarButtonsContainer.containers.delete(this)
134
+ this.innerHTML = ''
135
+ }
136
+
137
+ /**
138
+ * Добавляет новую общую кнопку в текущий контейнер правой панели
139
+ *
140
+ * @param {ButtonOptions} options Опции кнопки
141
+ */
142
+ addButton(options) {
143
+ const button = oom.div({
144
+ class: 'button',
145
+ title: options.title,
146
+ onclick: options.onclick
147
+ })
148
+
149
+ if (options.iconSVG) {
150
+ button({ innerHTML: options.iconSVG })
151
+ }
152
+
153
+ oom(this, button)
154
+ }
155
+
156
+ }
157
+
158
+
159
+ oom.define(RightSidebarButtonsContainer)
160
+
161
+
162
+ export const rightSidebar = {
163
+ addButton: (options) => RightSidebarButtonsContainer.addButton(options)
164
+ }
package/lib.js CHANGED
@@ -4,4 +4,5 @@ export * from './lib/hotkeys.js'
4
4
  export * from './lib/layout.js'
5
5
  export * from './lib/popup-dialog.js'
6
6
  export * from './lib/saby-lib/edo.js'
7
+ export * from './lib/saby-lib/right-sidebar.js'
7
8
  export * from './lib/saby-lib/rpc.js'
package/material.js CHANGED
@@ -2046,13 +2046,13 @@ const t$2=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeSh
2046
2046
  * Copyright 2017 Google LLC
2047
2047
  * SPDX-License-Identifier: BSD-3-Clause
2048
2048
  */
2049
- var t$1;const i$2=globalThis.trustedTypes,s$2=i$2?i$2.createPolicy("lit-html",{createHTML:t=>t}):void 0,e$2=`lit$${(Math.random()+"").slice(9)}$`,o$3="?"+e$2,n$2=`<${o$3}>`,l$4=document,h$1=(t="")=>l$4.createComment(t),r$2=t=>null===t||"object"!=typeof t&&"function"!=typeof t,d$1=Array.isArray,u=t=>{var i;return d$1(t)||"function"==typeof(null===(i=t)||void 0===i?void 0:i[Symbol.iterator])},c=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v=/-->/g,a=/>/g,f$1=/>|[ \n \r](?:([^\s"'>=/]+)([ \n \r]*=[ \n \r]*(?:[^ \n \r"'`<>=]|("|')|))|$)/g,_=/'/g,m=/"/g,g=/^(?:script|style|textarea)$/i,$=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),p=$(1),b=Symbol.for("lit-noChange"),T=Symbol.for("lit-nothing"),x=new WeakMap,w=(t,i,s)=>{var e,o;const n=null!==(e=null==s?void 0:s.renderBefore)&&void 0!==e?e:i;let l=n._$litPart$;if(void 0===l){const t=null!==(o=null==s?void 0:s.renderBefore)&&void 0!==o?o:null;n._$litPart$=l=new N(i.insertBefore(h$1(),t),t,void 0,null!=s?s:{});}return l._$AI(t),l},A=l$4.createTreeWalker(l$4,129,null,!1),C=(t,i)=>{const o=t.length-1,l=[];let h,r=2===i?"<svg>":"",d=c;for(let i=0;i<o;i++){const s=t[i];let o,u,$=-1,p=0;for(;p<s.length&&(d.lastIndex=p,u=d.exec(s),null!==u);)p=d.lastIndex,d===c?"!--"===u[1]?d=v:void 0!==u[1]?d=a:void 0!==u[2]?(g.test(u[2])&&(h=RegExp("</"+u[2],"g")),d=f$1):void 0!==u[3]&&(d=f$1):d===f$1?">"===u[0]?(d=null!=h?h:c,$=-1):void 0===u[1]?$=-2:($=d.lastIndex-u[2].length,o=u[1],d=void 0===u[3]?f$1:'"'===u[3]?m:_):d===m||d===_?d=f$1:d===v||d===a?d=c:(d=f$1,h=void 0);const y=d===f$1&&t[i+1].startsWith("/>")?" ":"";r+=d===c?s+n$2:$>=0?(l.push(o),s.slice(0,$)+"$lit$"+s.slice($)+e$2+y):s+e$2+(-2===$?(l.push(void 0),i):y);}const u=r+(t[o]||"<?>")+(2===i?"</svg>":"");return [void 0!==s$2?s$2.createHTML(u):u,l]};class P{constructor({strings:t,_$litType$:s},n){let l;this.parts=[];let r=0,d=0;const u=t.length-1,c=this.parts,[v,a]=C(t,s);if(this.el=P.createElement(v,n),A.currentNode=this.el.content,2===s){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes);}for(;null!==(l=A.nextNode())&&c.length<u;){if(1===l.nodeType){if(l.hasAttributes()){const t=[];for(const i of l.getAttributeNames())if(i.endsWith("$lit$")||i.startsWith(e$2)){const s=a[d++];if(t.push(i),void 0!==s){const t=l.getAttribute(s.toLowerCase()+"$lit$").split(e$2),i=/([.?@])?(.*)/.exec(s);c.push({type:1,index:r,name:i[2],strings:t,ctor:"."===i[1]?M:"?"===i[1]?k:"@"===i[1]?H:S});}else c.push({type:6,index:r});}for(const i of t)l.removeAttribute(i);}if(g.test(l.tagName)){const t=l.textContent.split(e$2),s=t.length-1;if(s>0){l.textContent=i$2?i$2.emptyScript:"";for(let i=0;i<s;i++)l.append(t[i],h$1()),A.nextNode(),c.push({type:2,index:++r});l.append(t[s],h$1());}}}else if(8===l.nodeType)if(l.data===o$3)c.push({type:2,index:r});else {let t=-1;for(;-1!==(t=l.data.indexOf(e$2,t+1));)c.push({type:7,index:r}),t+=e$2.length-1;}r++;}}static createElement(t,i){const s=l$4.createElement("template");return s.innerHTML=t,s}}function V(t,i,s=t,e){var o,n,l,h;if(i===b)return i;let d=void 0!==e?null===(o=s._$Cl)||void 0===o?void 0:o[e]:s._$Cu;const u=r$2(i)?void 0:i._$litDirective$;return (null==d?void 0:d.constructor)!==u&&(null===(n=null==d?void 0:d._$AO)||void 0===n||n.call(d,!1),void 0===u?d=void 0:(d=new u(t),d._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Cl)&&void 0!==l?l:h._$Cl=[])[e]=d:s._$Cu=d),void 0!==d&&(i=V(t,d._$AS(t,i.values),d,e)),i}class E{constructor(t,i){this.v=[],this._$AN=void 0,this._$AD=t,this._$AM=i;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}p(t){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:l$4).importNode(s,!0);A.currentNode=o;let n=A.nextNode(),h=0,r=0,d=e[0];for(;void 0!==d;){if(h===d.index){let i;2===d.type?i=new N(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new I(n,this,t)),this.v.push(i),d=e[++r];}h!==(null==d?void 0:d.index)&&(n=A.nextNode(),h++);}return o}m(t){let i=0;for(const s of this.v)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++;}}class N{constructor(t,i,s,e){var o;this.type=2,this._$AH=T,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cg=null===(o=null==e?void 0:e.isConnected)||void 0===o||o;}get _$AU(){var t,i;return null!==(i=null===(t=this._$AM)||void 0===t?void 0:t._$AU)&&void 0!==i?i:this._$Cg}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=V(this,t,i),r$2(t)?t===T||null==t||""===t?(this._$AH!==T&&this._$AR(),this._$AH=T):t!==this._$AH&&t!==b&&this.$(t):void 0!==t._$litType$?this.T(t):void 0!==t.nodeType?this.S(t):u(t)?this.M(t):this.$(t);}A(t,i=this._$AB){return this._$AA.parentNode.insertBefore(t,i)}S(t){this._$AH!==t&&(this._$AR(),this._$AH=this.A(t));}$(t){this._$AH!==T&&r$2(this._$AH)?this._$AA.nextSibling.data=t:this.S(l$4.createTextNode(t)),this._$AH=t;}T(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=P.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.m(s);else {const t=new E(o,this),i=t.p(this.options);t.m(s),this.S(i),this._$AH=t;}}_$AC(t){let i=x.get(t.strings);return void 0===i&&x.set(t.strings,i=new P(t)),i}M(t){d$1(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const o of t)e===i.length?i.push(s=new N(this.A(h$1()),this.A(h$1()),this,this.options)):s=i[e],s._$AI(o),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e);}_$AR(t=this._$AA.nextSibling,i){var s;for(null===(s=this._$AP)||void 0===s||s.call(this,!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i;}}setConnected(t){var i;void 0===this._$AM&&(this._$Cg=t,null===(i=this._$AP)||void 0===i||i.call(this,t));}}class S{constructor(t,i,s,e,o){this.type=1,this._$AH=T,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=T;}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,i=this,s,e){const o=this.strings;let n=!1;if(void 0===o)t=V(this,t,i,0),n=!r$2(t)||t!==this._$AH&&t!==b,n&&(this._$AH=t);else {const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=V(this,e[s+l],i,l),h===b&&(h=this._$AH[l]),n||(n=!r$2(h)||h!==this._$AH[l]),h===T?t=T:t!==T&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h;}n&&!e&&this.k(t);}k(t){t===T?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"");}}class M extends S{constructor(){super(...arguments),this.type=3;}k(t){this.element[this.name]=t===T?void 0:t;}}class k extends S{constructor(){super(...arguments),this.type=4;}k(t){t&&t!==T?this.element.setAttribute(this.name,""):this.element.removeAttribute(this.name);}}class H extends S{constructor(t,i,s,e,o){super(t,i,s,e,o),this.type=5;}_$AI(t,i=this){var s;if((t=null!==(s=V(this,t,i,0))&&void 0!==s?s:T)===b)return;const e=this._$AH,o=t===T&&e!==T||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==T&&(e===T||o);o&&this.element.removeEventListener(this.name,this,e),n&&this.element.addEventListener(this.name,this,t),this._$AH=t;}handleEvent(t){var i,s;"function"==typeof this._$AH?this._$AH.call(null!==(s=null===(i=this.options)||void 0===i?void 0:i.host)&&void 0!==s?s:this.element,t):this._$AH.handleEvent(t);}}class I{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s;}get _$AU(){return this._$AM._$AU}_$AI(t){V(this,t);}}const R=window.litHtmlPolyfillSupport;null==R||R(P,N),(null!==(t$1=globalThis.litHtmlVersions)&&void 0!==t$1?t$1:globalThis.litHtmlVersions=[]).push("2.0.1");
2049
+ var t$1;const i$2=globalThis.trustedTypes,s$2=i$2?i$2.createPolicy("lit-html",{createHTML:t=>t}):void 0,e$2=`lit$${(Math.random()+"").slice(9)}$`,o$3="?"+e$2,n$2=`<${o$3}>`,l$4=document,h$1=(t="")=>l$4.createComment(t),r$2=t=>null===t||"object"!=typeof t&&"function"!=typeof t,d$1=Array.isArray,u=t=>{var i;return d$1(t)||"function"==typeof(null===(i=t)||void 0===i?void 0:i[Symbol.iterator])},c=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v=/-->/g,a=/>/g,f$1=/>|[ \n \r](?:([^\s"'>=/]+)([ \n \r]*=[ \n \r]*(?:[^ \n \r"'`<>=]|("|')|))|$)/g,_=/'/g,m=/"/g,g=/^(?:script|style|textarea)$/i,$=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),p=$(1),b=Symbol.for("lit-noChange"),T=Symbol.for("lit-nothing"),x=new WeakMap,w=(t,i,s)=>{var e,o;const n=null!==(e=null==s?void 0:s.renderBefore)&&void 0!==e?e:i;let l=n._$litPart$;if(void 0===l){const t=null!==(o=null==s?void 0:s.renderBefore)&&void 0!==o?o:null;n._$litPart$=l=new N(i.insertBefore(h$1(),t),t,void 0,null!=s?s:{});}return l._$AI(t),l},A=l$4.createTreeWalker(l$4,129,null,!1),C=(t,i)=>{const o=t.length-1,l=[];let h,r=2===i?"<svg>":"",d=c;for(let i=0;i<o;i++){const s=t[i];let o,u,$=-1,p=0;for(;p<s.length&&(d.lastIndex=p,u=d.exec(s),null!==u);)p=d.lastIndex,d===c?"!--"===u[1]?d=v:void 0!==u[1]?d=a:void 0!==u[2]?(g.test(u[2])&&(h=RegExp("</"+u[2],"g")),d=f$1):void 0!==u[3]&&(d=f$1):d===f$1?">"===u[0]?(d=null!=h?h:c,$=-1):void 0===u[1]?$=-2:($=d.lastIndex-u[2].length,o=u[1],d=void 0===u[3]?f$1:'"'===u[3]?m:_):d===m||d===_?d=f$1:d===v||d===a?d=c:(d=f$1,h=void 0);const y=d===f$1&&t[i+1].startsWith("/>")?" ":"";r+=d===c?s+n$2:$>=0?(l.push(o),s.slice(0,$)+"$lit$"+s.slice($)+e$2+y):s+e$2+(-2===$?(l.push(void 0),i):y);}const u=r+(t[o]||"<?>")+(2===i?"</svg>":"");return [void 0!==s$2?s$2.createHTML(u):u,l]};class P{constructor({strings:t,_$litType$:s},n){let l;this.parts=[];let r=0,d=0;const u=t.length-1,c=this.parts,[v,a]=C(t,s);if(this.el=P.createElement(v,n),A.currentNode=this.el.content,2===s){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes);}for(;null!==(l=A.nextNode())&&c.length<u;){if(1===l.nodeType){if(l.hasAttributes()){const t=[];for(const i of l.getAttributeNames())if(i.endsWith("$lit$")||i.startsWith(e$2)){const s=a[d++];if(t.push(i),void 0!==s){const t=l.getAttribute(s.toLowerCase()+"$lit$").split(e$2),i=/([.?@])?(.*)/.exec(s);c.push({type:1,index:r,name:i[2],strings:t,ctor:"."===i[1]?M:"?"===i[1]?H:"@"===i[1]?I:S});}else c.push({type:6,index:r});}for(const i of t)l.removeAttribute(i);}if(g.test(l.tagName)){const t=l.textContent.split(e$2),s=t.length-1;if(s>0){l.textContent=i$2?i$2.emptyScript:"";for(let i=0;i<s;i++)l.append(t[i],h$1()),A.nextNode(),c.push({type:2,index:++r});l.append(t[s],h$1());}}}else if(8===l.nodeType)if(l.data===o$3)c.push({type:2,index:r});else {let t=-1;for(;-1!==(t=l.data.indexOf(e$2,t+1));)c.push({type:7,index:r}),t+=e$2.length-1;}r++;}}static createElement(t,i){const s=l$4.createElement("template");return s.innerHTML=t,s}}function V(t,i,s=t,e){var o,n,l,h;if(i===b)return i;let d=void 0!==e?null===(o=s._$Cl)||void 0===o?void 0:o[e]:s._$Cu;const u=r$2(i)?void 0:i._$litDirective$;return (null==d?void 0:d.constructor)!==u&&(null===(n=null==d?void 0:d._$AO)||void 0===n||n.call(d,!1),void 0===u?d=void 0:(d=new u(t),d._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Cl)&&void 0!==l?l:h._$Cl=[])[e]=d:s._$Cu=d),void 0!==d&&(i=V(t,d._$AS(t,i.values),d,e)),i}class E{constructor(t,i){this.v=[],this._$AN=void 0,this._$AD=t,this._$AM=i;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}p(t){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:l$4).importNode(s,!0);A.currentNode=o;let n=A.nextNode(),h=0,r=0,d=e[0];for(;void 0!==d;){if(h===d.index){let i;2===d.type?i=new N(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new L(n,this,t)),this.v.push(i),d=e[++r];}h!==(null==d?void 0:d.index)&&(n=A.nextNode(),h++);}return o}m(t){let i=0;for(const s of this.v)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++;}}class N{constructor(t,i,s,e){var o;this.type=2,this._$AH=T,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cg=null===(o=null==e?void 0:e.isConnected)||void 0===o||o;}get _$AU(){var t,i;return null!==(i=null===(t=this._$AM)||void 0===t?void 0:t._$AU)&&void 0!==i?i:this._$Cg}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=V(this,t,i),r$2(t)?t===T||null==t||""===t?(this._$AH!==T&&this._$AR(),this._$AH=T):t!==this._$AH&&t!==b&&this.$(t):void 0!==t._$litType$?this.T(t):void 0!==t.nodeType?this.S(t):u(t)?this.M(t):this.$(t);}A(t,i=this._$AB){return this._$AA.parentNode.insertBefore(t,i)}S(t){this._$AH!==t&&(this._$AR(),this._$AH=this.A(t));}$(t){this._$AH!==T&&r$2(this._$AH)?this._$AA.nextSibling.data=t:this.S(l$4.createTextNode(t)),this._$AH=t;}T(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=P.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.m(s);else {const t=new E(o,this),i=t.p(this.options);t.m(s),this.S(i),this._$AH=t;}}_$AC(t){let i=x.get(t.strings);return void 0===i&&x.set(t.strings,i=new P(t)),i}M(t){d$1(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const o of t)e===i.length?i.push(s=new N(this.A(h$1()),this.A(h$1()),this,this.options)):s=i[e],s._$AI(o),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e);}_$AR(t=this._$AA.nextSibling,i){var s;for(null===(s=this._$AP)||void 0===s||s.call(this,!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i;}}setConnected(t){var i;void 0===this._$AM&&(this._$Cg=t,null===(i=this._$AP)||void 0===i||i.call(this,t));}}class S{constructor(t,i,s,e,o){this.type=1,this._$AH=T,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=T;}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,i=this,s,e){const o=this.strings;let n=!1;if(void 0===o)t=V(this,t,i,0),n=!r$2(t)||t!==this._$AH&&t!==b,n&&(this._$AH=t);else {const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=V(this,e[s+l],i,l),h===b&&(h=this._$AH[l]),n||(n=!r$2(h)||h!==this._$AH[l]),h===T?t=T:t!==T&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h;}n&&!e&&this.k(t);}k(t){t===T?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"");}}class M extends S{constructor(){super(...arguments),this.type=3;}k(t){this.element[this.name]=t===T?void 0:t;}}const k=i$2?i$2.emptyScript:"";class H extends S{constructor(){super(...arguments),this.type=4;}k(t){t&&t!==T?this.element.setAttribute(this.name,k):this.element.removeAttribute(this.name);}}class I extends S{constructor(t,i,s,e,o){super(t,i,s,e,o),this.type=5;}_$AI(t,i=this){var s;if((t=null!==(s=V(this,t,i,0))&&void 0!==s?s:T)===b)return;const e=this._$AH,o=t===T&&e!==T||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==T&&(e===T||o);o&&this.element.removeEventListener(this.name,this,e),n&&this.element.addEventListener(this.name,this,t),this._$AH=t;}handleEvent(t){var i,s;"function"==typeof this._$AH?this._$AH.call(null!==(s=null===(i=this.options)||void 0===i?void 0:i.host)&&void 0!==s?s:this.element,t):this._$AH.handleEvent(t);}}class L{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s;}get _$AU(){return this._$AM._$AU}_$AI(t){V(this,t);}}const z=window.litHtmlPolyfillSupport;null==z||z(P,N),(null!==(t$1=globalThis.litHtmlVersions)&&void 0!==t$1?t$1:globalThis.litHtmlVersions=[]).push("2.0.2");
2050
2050
 
2051
2051
  /**
2052
2052
  * @license
2053
2053
  * Copyright 2017 Google LLC
2054
2054
  * SPDX-License-Identifier: BSD-3-Clause
2055
- */var l$3,o$2;class s$1 extends n$3{constructor(){super(...arguments),this.renderOptions={host:this},this._$Dt=void 0;}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Dt=w(i,this.renderRoot,this.renderOptions);}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Dt)||void 0===t||t.setConnected(!0);}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Dt)||void 0===t||t.setConnected(!1);}render(){return b}}s$1.finalized=!0,s$1._$litElement$=!0,null===(l$3=globalThis.litElementHydrateSupport)||void 0===l$3||l$3.call(globalThis,{LitElement:s$1});const n$1=globalThis.litElementPolyfillSupport;null==n$1||n$1({LitElement:s$1});(null!==(o$2=globalThis.litElementVersions)&&void 0!==o$2?o$2:globalThis.litElementVersions=[]).push("3.0.1");
2055
+ */var l$3,o$2;class s$1 extends n$3{constructor(){super(...arguments),this.renderOptions={host:this},this._$Dt=void 0;}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Dt=w(i,this.renderRoot,this.renderOptions);}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Dt)||void 0===t||t.setConnected(!0);}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Dt)||void 0===t||t.setConnected(!1);}render(){return b}}s$1.finalized=!0,s$1._$litElement$=!0,null===(l$3=globalThis.litElementHydrateSupport)||void 0===l$3||l$3.call(globalThis,{LitElement:s$1});const n$1=globalThis.litElementPolyfillSupport;null==n$1||n$1({LitElement:s$1});(null!==(o$2=globalThis.litElementVersions)&&void 0!==o$2?o$2:globalThis.litElementVersions=[]).push("3.0.2");
2056
2056
 
2057
2057
  /**
2058
2058
  * @license
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "repository": "github:saby-customizer/saby-customizer.github.io",
11
11
  "license": "Unlicense",
12
- "version": "0.0.0-pre.17",
12
+ "version": "0.0.0-pre.21",
13
13
  "type": "module",
14
14
  "main": "./userscript.js",
15
15
  "exports": {
@@ -38,7 +38,7 @@
38
38
  "@material/mwc-textarea": "^0.25.3",
39
39
  "@material/mwc-top-app-bar": "^0.25.3",
40
40
  "@material/mwc-snackbar": "^0.25.3",
41
- "dexie": "^3.0.3"
41
+ "dexie": "^3.2.0"
42
42
  },
43
43
  "scripts": {
44
44
  "prepack": "cd .. && npm run build"