saby-customizer 0.0.0-pre.10
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/README.md +8 -0
- package/features/git-branch.js +92 -0
- package/lib/dashboard.js +55 -0
- package/lib/database.js +9 -0
- package/lib/hotkeys.js +21 -0
- package/lib/layout.js +35 -0
- package/lib/material.js +25 -0
- package/lib/popup-dialog.js +111 -0
- package/lib.js +4 -0
- package/material.js +6429 -0
- package/package.json +32 -0
- package/saby-customizer-0.0.0-pre.8.tgz +0 -0
- package/saby-lib/cloud-statistic.js +2 -0
- package/saby-lib/edo.js +161 -0
- package/userscript.js +30 -0
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "saby-customizer",
|
|
3
|
+
"description": "Персональная настройка saby приложений для решения повседневных задач, и не только...",
|
|
4
|
+
"author": "IgorNovozhilov",
|
|
5
|
+
"homepage": "https://saby-customizer.github.io",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/saby-customizer/saby-customizer.github.io/issues",
|
|
8
|
+
"email": "ia.novozhilov@tensor.ru"
|
|
9
|
+
},
|
|
10
|
+
"repository": "github:saby-customizer/saby-customizer.github.io",
|
|
11
|
+
"license": "Unlicense",
|
|
12
|
+
"version": "0.0.0-pre.10",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./userscript.js",
|
|
16
|
+
"./lib": "./lib/index.js"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@notml/core": "^0.1.0-pre.7",
|
|
20
|
+
"@material/mwc-dialog": "^0.25.1",
|
|
21
|
+
"@material/mwc-icon-button": "^0.25.1",
|
|
22
|
+
"@material/mwc-tab-bar": "^0.25.1",
|
|
23
|
+
"@material/mwc-top-app-bar": "^0.25.1",
|
|
24
|
+
"dexie": "^3.0.3"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"prepack": "cd .. && npm run build"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
Binary file
|
package/saby-lib/edo.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const replaceDocTypeName = {
|
|
2
|
+
'Error': 'Ошибка',
|
|
3
|
+
'Task to Development': 'Задача',
|
|
4
|
+
'Задача в разработку': 'Задача'
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Приведение даты к формату
|
|
10
|
+
*
|
|
11
|
+
* @param {Date} date Дата
|
|
12
|
+
* @returns {string} dd.mm.yy
|
|
13
|
+
*/
|
|
14
|
+
function getStrDate(date) {
|
|
15
|
+
if (date) {
|
|
16
|
+
const d = ('0' + date.getDate()).slice(-2)
|
|
17
|
+
const m = ('0' + (date.getMonth() + 1)).slice(-2)
|
|
18
|
+
const y = String(date.getFullYear()).slice(-2)
|
|
19
|
+
|
|
20
|
+
return d + '.' + m + '.' + y
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Разбирает формат RichEditor и приводить в нестилизированный текст
|
|
27
|
+
*
|
|
28
|
+
* @param {*} json Объет с RichEditorJSON
|
|
29
|
+
* @returns {string} Тексто документа
|
|
30
|
+
*/
|
|
31
|
+
function parseRichEditorJSON(json) {
|
|
32
|
+
let text = ''
|
|
33
|
+
|
|
34
|
+
for (const item of json) {
|
|
35
|
+
const [tag] = item
|
|
36
|
+
const data = item.slice(1)
|
|
37
|
+
|
|
38
|
+
switch (tag) {
|
|
39
|
+
case 'p':
|
|
40
|
+
for (const itemData of data) {
|
|
41
|
+
const type = typeof itemData
|
|
42
|
+
|
|
43
|
+
if (type === 'string') {
|
|
44
|
+
text += itemData
|
|
45
|
+
} else if (itemData instanceof Array) {
|
|
46
|
+
text += parseRichEditorJSON(itemData[0] instanceof Array ? itemData : [itemData])
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
text += '\n'
|
|
50
|
+
break
|
|
51
|
+
case 'a':
|
|
52
|
+
text += data[0].href
|
|
53
|
+
break
|
|
54
|
+
default:
|
|
55
|
+
for (const itemData of data) {
|
|
56
|
+
const type = typeof itemData
|
|
57
|
+
|
|
58
|
+
if (type === 'string') {
|
|
59
|
+
text += itemData
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return text
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @typedef CardData Данные карточки документа
|
|
71
|
+
* @property {string} number Номер документа
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* @typedef OpenCardsFilter Фильтры для выборки документов
|
|
75
|
+
* @property {Array<string>} [names] Фильтр по названию документа
|
|
76
|
+
* @property {boolean} [hasVersion] Документ включен хотя бы в 1 веху
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* Собирает из верстки страницы список открытых в данный момент карточек документов ЭДО
|
|
80
|
+
*
|
|
81
|
+
* @param {OpenCardsFilter} [filter] Параметры фильтрации документов
|
|
82
|
+
* @returns {Array<{element:HTMLElement, data:CardData}>} Список открытых карточке документов
|
|
83
|
+
*/
|
|
84
|
+
export function getListOfOpenCards(filter = {}) {
|
|
85
|
+
const cardNodes = document.querySelectorAll('.edo3-Dialog')
|
|
86
|
+
const cards = []
|
|
87
|
+
|
|
88
|
+
for (const cardNode of Array.from(cardNodes)) {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
const { controlNodes } = cardNode
|
|
91
|
+
|
|
92
|
+
if (controlNodes) {
|
|
93
|
+
/** @type {{element:HTMLElement,options:{record:{get:(name:string)=>any}}}} */
|
|
94
|
+
const control = controlNodes.at()
|
|
95
|
+
const { element } = control
|
|
96
|
+
const record = control?.options?.record
|
|
97
|
+
const data = record && {
|
|
98
|
+
number: record.get('Номер'),
|
|
99
|
+
date: getStrDate(record.get('Дата')),
|
|
100
|
+
name: record.get('РП.Документ').get('Регламент').get('Название'),
|
|
101
|
+
uuid: record.get('РП.Документ').get('ИдентификаторПереписки'),
|
|
102
|
+
author: record.get('ЛицоСоздал.Название') || record.get('Сотрудник.Название'),
|
|
103
|
+
milestones: [],
|
|
104
|
+
version: 'dev'
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (data) {
|
|
108
|
+
const milestonesRS = record.get('РП.ВехаДокумента')
|
|
109
|
+
|
|
110
|
+
data.name = replaceDocTypeName[data.name] || data.name
|
|
111
|
+
if (filter.names) {
|
|
112
|
+
if (!filter.names.includes(data.name)) {
|
|
113
|
+
continue
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Список вех
|
|
118
|
+
milestonesRS.forEach(milestoneRec => {
|
|
119
|
+
const milestoneName = milestoneRec.get('ДокументРасширение.Название')
|
|
120
|
+
const version = milestoneName.replace(/(^\d+.\d+).*/, '$1')
|
|
121
|
+
|
|
122
|
+
if ((/^\d+.\d+$/).test(version)) {
|
|
123
|
+
data.milestones.push(version)
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
if (data.milestones.length > 0) {
|
|
127
|
+
[data.version] = data.milestones
|
|
128
|
+
} else {
|
|
129
|
+
if (filter.hasVersion) {
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Прямая ссылка на карточку
|
|
135
|
+
data.url = location.protocol + '//' + location.host + '/doc/' + data.uuid
|
|
136
|
+
|
|
137
|
+
// Получение краткого описания
|
|
138
|
+
data.description = record.get('РазличныеДокументы.ИнформацияJSON')
|
|
139
|
+
if (data.description) {
|
|
140
|
+
try {
|
|
141
|
+
data.description = JSON.parse(data.description)
|
|
142
|
+
data.description = parseRichEditorJSON(data.description)
|
|
143
|
+
if (data.description.length > 1024) {
|
|
144
|
+
data.description = data.description.substring(0, 1021) + '...'
|
|
145
|
+
}
|
|
146
|
+
data.description = (data.description.match(/.{1,127}/g) || []).join('\n')
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(error.stack || error)
|
|
149
|
+
data.description = 'Не удалось получить описание задачи'
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
data.description = 'Описание задачи не заполнено'
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
cards.push({ element, data })
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return cards
|
|
161
|
+
}
|
package/userscript.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { oom } from '@notml/core'
|
|
2
|
+
|
|
3
|
+
(async () => {
|
|
4
|
+
// Отключение блокировки внешних элементов для mwc-dialog, слишком дорогая операция для онлайна
|
|
5
|
+
Object.defineProperty(document, '$blockingElements', {
|
|
6
|
+
set: () => { },
|
|
7
|
+
get: () => ({ push: () => { }, remove: () => { } })
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
// Компоненты material используемые в проекте
|
|
11
|
+
// await import('./lib/material.js')
|
|
12
|
+
// @ts-ignore https://github.com/material-components/material-web/issues/2780
|
|
13
|
+
await import('./material.js')
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
// Библиотеки компонентов плагина
|
|
17
|
+
// TODO: Перевести на опциональную загрузку
|
|
18
|
+
// await import('./lib/dashboard.js')
|
|
19
|
+
await import('./features/git-branch.js')
|
|
20
|
+
|
|
21
|
+
// @font-face doesn't work with Shadow DOM https://github.com/mdn/interactive-examples/issues/887
|
|
22
|
+
// https://wiki.csswg.org/spec/css-scoping
|
|
23
|
+
// https://drafts.csswg.org/css-scoping/#shadow-names
|
|
24
|
+
oom(document.head, oom
|
|
25
|
+
// Подключение стилей material только внутри теневого DOM
|
|
26
|
+
.link({ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap' })
|
|
27
|
+
.link({ rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }))
|
|
28
|
+
})().catch(e => {
|
|
29
|
+
console.error(e.stack || e)
|
|
30
|
+
})
|