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/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
@@ -0,0 +1,2 @@
1
+ // Собрать стату по использованию фич кастомайзера
2
+ // https://online.sbis.ru/news/4a005fd5-c99b-4e8d-a78b-eeb67b78d892
@@ -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
+ })