@fiduswriter/bibliography-manager 0.1.6 → 0.1.8
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/dist/database/index.d.ts +12 -11
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +22 -16
- package/dist/database/index.js.map +1 -1
- package/dist/database/server_connector.d.ts +14 -15
- package/dist/database/server_connector.d.ts.map +1 -1
- package/dist/database/server_connector.js +17 -9
- package/dist/database/server_connector.js.map +1 -1
- package/dist/export/index.d.ts +6 -4
- package/dist/export/index.d.ts.map +1 -1
- package/dist/export/index.js +7 -1
- package/dist/export/index.js.map +1 -1
- package/dist/form/cats.d.ts +5 -4
- package/dist/form/cats.d.ts.map +1 -1
- package/dist/form/cats.js +2 -0
- package/dist/form/cats.js.map +1 -1
- package/dist/form/fields/date.d.ts +4 -4
- package/dist/form/fields/date.d.ts.map +1 -1
- package/dist/form/fields/date.js +5 -1
- package/dist/form/fields/date.js.map +1 -1
- package/dist/form/fields/key.d.ts +11 -9
- package/dist/form/fields/key.d.ts.map +1 -1
- package/dist/form/fields/key.js +13 -6
- package/dist/form/fields/key.js.map +1 -1
- package/dist/form/fields/key_list.d.ts +10 -8
- package/dist/form/fields/key_list.d.ts.map +1 -1
- package/dist/form/fields/key_list.js +4 -0
- package/dist/form/fields/key_list.js.map +1 -1
- package/dist/form/fields/literal.d.ts +4 -4
- package/dist/form/fields/literal.d.ts.map +1 -1
- package/dist/form/fields/literal.js +2 -1
- package/dist/form/fields/literal.js.map +1 -1
- package/dist/form/fields/literal_list.d.ts +8 -7
- package/dist/form/fields/literal_list.d.ts.map +1 -1
- package/dist/form/fields/literal_list.js +3 -0
- package/dist/form/fields/literal_list.js.map +1 -1
- package/dist/form/fields/literal_long.d.ts +4 -4
- package/dist/form/fields/literal_long.d.ts.map +1 -1
- package/dist/form/fields/literal_long.js +1 -0
- package/dist/form/fields/literal_long.js.map +1 -1
- package/dist/form/fields/name.d.ts +10 -27
- package/dist/form/fields/name.d.ts.map +1 -1
- package/dist/form/fields/name.js +22 -18
- package/dist/form/fields/name.js.map +1 -1
- package/dist/form/fields/name_list.d.ts +9 -7
- package/dist/form/fields/name_list.d.ts.map +1 -1
- package/dist/form/fields/name_list.js +5 -2
- package/dist/form/fields/name_list.js.map +1 -1
- package/dist/form/fields/range.d.ts +10 -8
- package/dist/form/fields/range.d.ts.map +1 -1
- package/dist/form/fields/range.js +13 -9
- package/dist/form/fields/range.js.map +1 -1
- package/dist/form/fields/range_list.d.ts +9 -7
- package/dist/form/fields/range_list.d.ts.map +1 -1
- package/dist/form/fields/range_list.js +3 -0
- package/dist/form/fields/range_list.js.map +1 -1
- package/dist/form/fields/tag_list.d.ts +7 -6
- package/dist/form/fields/tag_list.d.ts.map +1 -1
- package/dist/form/fields/tag_list.js +3 -0
- package/dist/form/fields/tag_list.js.map +1 -1
- package/dist/form/fields/title.d.ts +4 -4
- package/dist/form/fields/title.d.ts.map +1 -1
- package/dist/form/fields/title.js +1 -0
- package/dist/form/fields/title.js.map +1 -1
- package/dist/form/fields/uri.d.ts +4 -4
- package/dist/form/fields/uri.d.ts.map +1 -1
- package/dist/form/fields/uri.js +5 -1
- package/dist/form/fields/uri.js.map +1 -1
- package/dist/form/fields/verbatim.d.ts +4 -4
- package/dist/form/fields/verbatim.d.ts.map +1 -1
- package/dist/form/fields/verbatim.js +5 -1
- package/dist/form/fields/verbatim.js.map +1 -1
- package/dist/form/index.d.ts +32 -30
- package/dist/form/index.d.ts.map +1 -1
- package/dist/form/index.js +33 -11
- package/dist/form/index.js.map +1 -1
- package/dist/form/strings.d.ts +11 -11
- package/dist/form/strings.d.ts.map +1 -1
- package/dist/form/strings.js +5 -5
- package/dist/form/strings.js.map +1 -1
- package/dist/form/templates.d.ts +6 -5
- package/dist/form/templates.d.ts.map +1 -1
- package/dist/form/templates.js +2 -2
- package/dist/form/templates.js.map +1 -1
- package/dist/import/bibliography_import.d.ts +20 -7
- package/dist/import/bibliography_import.d.ts.map +1 -1
- package/dist/import/bibliography_import.js +15 -7
- package/dist/import/bibliography_import.js.map +1 -1
- package/dist/import/dialog.d.ts +6 -5
- package/dist/import/dialog.d.ts.map +1 -1
- package/dist/import/dialog.js +27 -12
- package/dist/import/dialog.js.map +1 -1
- package/dist/import/index.d.ts +2 -0
- package/dist/import/index.d.ts.map +1 -1
- package/dist/import/index.js +5 -0
- package/dist/import/index.js.map +1 -1
- package/dist/import/templates.d.ts +2 -1
- package/dist/import/templates.d.ts.map +1 -1
- package/dist/import/templates.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/overview/index.d.ts +43 -27
- package/dist/overview/index.d.ts.map +1 -1
- package/dist/overview/index.js +59 -23
- package/dist/overview/index.js.map +1 -1
- package/dist/overview/menu.d.ts +13 -12
- package/dist/overview/menu.d.ts.map +1 -1
- package/dist/overview/menu.js +13 -10
- package/dist/overview/menu.js.map +1 -1
- package/dist/overview/templates.d.ts +5 -3
- package/dist/overview/templates.d.ts.map +1 -1
- package/dist/overview/templates.js.map +1 -1
- package/dist/plugins/bibliography_overview/index.d.ts +1 -1
- package/dist/plugins/bibliography_overview/index.d.ts.map +1 -1
- package/dist/plugins/bibliography_overview/index.js.map +1 -1
- package/dist/schema/csl_bib.d.ts +1 -1
- package/dist/schema/literal.d.ts +1 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/literal_long.d.ts +1 -1
- package/dist/schema/literal_long.d.ts.map +1 -1
- package/dist/schema/literal_long.js +1 -7
- package/dist/schema/literal_long.js.map +1 -1
- package/dist/schema/title.d.ts +1 -1
- package/dist/schema/title.d.ts.map +1 -1
- package/dist/schema/title.js.map +1 -1
- package/dist/tools.d.ts +4 -3
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js.map +1 -1
- package/dist/types/biblio.d.ts +138 -0
- package/dist/types/biblio.d.ts.map +1 -0
- package/dist/types/biblio.js +2 -0
- package/dist/types/biblio.js.map +1 -0
- package/package.json +1 -1
- package/src/database/{index.js → index.ts} +60 -38
- package/src/database/server_connector.ts +92 -0
- package/src/export/{index.js → index.ts} +16 -4
- package/src/form/{cats.js → cats.ts} +11 -3
- package/src/form/fields/{date.js → date.ts} +10 -5
- package/src/form/fields/{key.js → key.ts} +37 -19
- package/src/form/fields/{key_list.js → key_list.ts} +18 -7
- package/src/form/fields/{literal.js → literal.ts} +11 -5
- package/src/form/fields/{literal_list.js → literal_list.ts} +19 -10
- package/src/form/fields/{literal_long.js → literal_long.ts} +6 -4
- package/src/form/fields/{name.js → name.ts} +53 -39
- package/src/form/fields/name_list.ts +49 -0
- package/src/form/fields/{range.js → range.ts} +34 -22
- package/src/form/fields/{range_list.js → range_list.ts} +17 -10
- package/src/form/fields/{tag_list.js → tag_list.ts} +9 -5
- package/src/form/fields/{title.js → title.ts} +6 -4
- package/src/form/fields/{uri.js → uri.ts} +11 -6
- package/src/form/fields/{verbatim.js → verbatim.ts} +10 -5
- package/src/form/{index.js → index.ts} +113 -60
- package/src/form/{strings.js → strings.ts} +24 -22
- package/src/form/{templates.js → templates.ts} +14 -5
- package/src/global.d.ts +75 -0
- package/src/import/{bibliography_import.js → bibliography_import.ts} +42 -16
- package/src/import/{dialog.js → dialog.ts} +47 -23
- package/src/import/index.ts +14 -0
- package/src/import/{templates.js → templates.ts} +1 -1
- package/src/overview/{index.js → index.ts} +150 -81
- package/src/overview/{menu.js → menu.ts} +18 -12
- package/src/overview/{templates.js → templates.ts} +3 -2
- package/src/plugins/bibliography_overview/index.ts +1 -0
- package/src/schema/{literal_long.js → literal_long.ts} +3 -8
- package/src/schema/{title.js → title.ts} +1 -1
- package/src/{tools.js → tools.ts} +7 -5
- package/src/types/biblio.ts +189 -0
- package/src/database/server_connector.js +0 -57
- package/src/form/fields/name_list.js +0 -42
- package/src/import/index.js +0 -2
- package/src/plugins/bibliography_overview/index.js +0 -1
- /package/src/{index.js → index.ts} +0 -0
- /package/src/schema/{literal.js → literal.ts} +0 -0
|
@@ -12,17 +12,51 @@ import {
|
|
|
12
12
|
setDocTitle,
|
|
13
13
|
whenReady
|
|
14
14
|
} from "fwtoolkit"
|
|
15
|
+
import type {DialogButtonSpec} from "fwtoolkit/dialog"
|
|
16
|
+
import type {DatatableBulk} from "fwtoolkit"
|
|
17
|
+
import type {OverviewMenuModel} from "fwtoolkit/overview_menu"
|
|
18
|
+
import type {ContentMenuInit} from "fwtoolkit/content_menu"
|
|
19
|
+
import type {DataTable} from "simple-datatables"
|
|
15
20
|
import {baseBodyTemplate, FeedbackTab, SiteMenu} from "@fiduswriter/common"
|
|
16
|
-
import {plugins} from "../plugins/bibliography_overview/index.js"
|
|
21
|
+
import {plugins as defaultBibPlugins} from "../plugins/bibliography_overview/index.js"
|
|
17
22
|
import {getBibTypeTitle} from "../form/strings.js"
|
|
18
23
|
import {litToText, nameToText} from "../tools.js"
|
|
24
|
+
import type {
|
|
25
|
+
BibCategory,
|
|
26
|
+
BibliographyApp,
|
|
27
|
+
IdTranslation,
|
|
28
|
+
NameDictObject,
|
|
29
|
+
NodeArray
|
|
30
|
+
} from "../types/biblio.js"
|
|
19
31
|
import {bulkMenuModel, menuModel} from "./menu.js"
|
|
20
32
|
import {editCategoriesTemplate} from "./templates.js"
|
|
21
33
|
|
|
34
|
+
interface PluginExport {
|
|
35
|
+
new (overview: BibliographyOverview): {init: () => Promise<unknown> | void}
|
|
36
|
+
name: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type BibPlugin = [string, Record<string, PluginExport>]
|
|
40
|
+
|
|
22
41
|
export class BibliographyOverview {
|
|
23
|
-
|
|
42
|
+
app: BibliographyApp
|
|
43
|
+
user: Record<string, unknown>
|
|
44
|
+
bibPlugins: BibPlugin[]
|
|
45
|
+
lastSort: {column: number; dir: "asc" | "desc"}
|
|
46
|
+
dom!: HTMLElement
|
|
47
|
+
overviewTable?: OverviewDataTable
|
|
48
|
+
table?: DataTable
|
|
49
|
+
dtBulk?: DatatableBulk
|
|
50
|
+
menu?: OverviewMenuView
|
|
51
|
+
plugins?: Record<string, {init: () => Promise<unknown> | void}>
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
{app, user}: {app: BibliographyApp; user: Record<string, unknown>},
|
|
55
|
+
bibPlugins: BibPlugin[] = defaultBibPlugins as BibPlugin[]
|
|
56
|
+
) {
|
|
24
57
|
this.app = app
|
|
25
58
|
this.user = user
|
|
59
|
+
this.bibPlugins = bibPlugins
|
|
26
60
|
|
|
27
61
|
this.lastSort = {column: 0, dir: "asc"}
|
|
28
62
|
}
|
|
@@ -30,12 +64,15 @@ export class BibliographyOverview {
|
|
|
30
64
|
/** Bind the init function to doc loading.
|
|
31
65
|
* @function bind
|
|
32
66
|
*/
|
|
33
|
-
init() {
|
|
67
|
+
init(): Promise<void> {
|
|
34
68
|
return whenReady().then(() => {
|
|
35
69
|
this.render()
|
|
36
70
|
const smenu = new SiteMenu(this.app, "bibliography")
|
|
37
71
|
smenu.init()
|
|
38
|
-
this.menu = new OverviewMenuView(
|
|
72
|
+
this.menu = new OverviewMenuView(
|
|
73
|
+
this,
|
|
74
|
+
menuModel as () => OverviewMenuModel
|
|
75
|
+
)
|
|
39
76
|
this.menu.init()
|
|
40
77
|
this.setBibCategoryList(this.app.bibDB.cats)
|
|
41
78
|
this.initTable(Object.keys(this.app.bibDB.db))
|
|
@@ -47,7 +84,7 @@ export class BibliographyOverview {
|
|
|
47
84
|
})
|
|
48
85
|
}
|
|
49
86
|
|
|
50
|
-
render() {
|
|
87
|
+
render(): void {
|
|
51
88
|
this.dom = document.createElement("body")
|
|
52
89
|
this.dom.innerHTML = baseBodyTemplate({
|
|
53
90
|
contents: "",
|
|
@@ -66,7 +103,7 @@ export class BibliographyOverview {
|
|
|
66
103
|
feedbackTab.init()
|
|
67
104
|
}
|
|
68
105
|
|
|
69
|
-
onResize() {
|
|
106
|
+
onResize(): void {
|
|
70
107
|
if (!this.table) {
|
|
71
108
|
return
|
|
72
109
|
}
|
|
@@ -74,18 +111,18 @@ export class BibliographyOverview {
|
|
|
74
111
|
}
|
|
75
112
|
|
|
76
113
|
/* Initialize the overview table */
|
|
77
|
-
initTable(ids) {
|
|
114
|
+
initTable(ids: string[]): void {
|
|
78
115
|
if (this.overviewTable) {
|
|
79
116
|
this.overviewTable.destroy()
|
|
80
|
-
this.overviewTable =
|
|
117
|
+
this.overviewTable = undefined
|
|
81
118
|
}
|
|
82
|
-
this.table =
|
|
83
|
-
this.dtBulk =
|
|
119
|
+
this.table = undefined
|
|
120
|
+
this.dtBulk = undefined
|
|
84
121
|
|
|
85
|
-
const contentsEl = this.dom.querySelector(".fw-contents")
|
|
122
|
+
const contentsEl = this.dom.querySelector(".fw-contents") as HTMLElement
|
|
86
123
|
contentsEl.innerHTML = ""
|
|
87
124
|
|
|
88
|
-
const hiddenCols = [0]
|
|
125
|
+
const hiddenCols: number[] = [0]
|
|
89
126
|
|
|
90
127
|
if (window.innerWidth < 500) {
|
|
91
128
|
hiddenCols.push(1)
|
|
@@ -123,8 +160,8 @@ export class BibliographyOverview {
|
|
|
123
160
|
data: ids.map(id => this.createTableRow(id)),
|
|
124
161
|
idColumn: 0,
|
|
125
162
|
checkboxColumn: 1,
|
|
126
|
-
bulkMenu: bulkMenuModel(),
|
|
127
|
-
bulkMenuPage: this,
|
|
163
|
+
bulkMenu: bulkMenuModel() as unknown as ContentMenuInit,
|
|
164
|
+
bulkMenuPage: this as Record<string, unknown>,
|
|
128
165
|
searchable: true,
|
|
129
166
|
scrollY: `${Math.max(window.innerHeight - 360, 100)}px`,
|
|
130
167
|
tabIndex: 1,
|
|
@@ -145,19 +182,22 @@ export class BibliographyOverview {
|
|
|
145
182
|
`<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>`,
|
|
146
183
|
rowRender: (row, tr, _index) => {
|
|
147
184
|
const id = row.cells[0].data
|
|
148
|
-
const inputNode
|
|
185
|
+
const inputNode: {
|
|
186
|
+
nodeName: string
|
|
187
|
+
attributes: Record<string, string | boolean | number>
|
|
188
|
+
} = {
|
|
149
189
|
nodeName: "input",
|
|
150
190
|
attributes: {
|
|
151
191
|
type: "checkbox",
|
|
152
192
|
class: "entry-select fw-check",
|
|
153
|
-
"data-id": id,
|
|
193
|
+
"data-id": id as number,
|
|
154
194
|
id: `bib-${id}`
|
|
155
195
|
}
|
|
156
196
|
}
|
|
157
197
|
if (row.cells[1].data) {
|
|
158
198
|
inputNode.attributes.checked = true
|
|
159
199
|
}
|
|
160
|
-
tr.childNodes[0].childNodes = [
|
|
200
|
+
;(tr as {childNodes: {childNodes: unknown[]}[]}).childNodes[0].childNodes = [
|
|
161
201
|
inputNode,
|
|
162
202
|
{
|
|
163
203
|
nodeName: "label",
|
|
@@ -171,22 +211,22 @@ export class BibliographyOverview {
|
|
|
171
211
|
if (this.getSelected().length > 0) {
|
|
172
212
|
return
|
|
173
213
|
}
|
|
174
|
-
const rowIndex = this.table
|
|
175
|
-
const editButton = this.table
|
|
214
|
+
const rowIndex = this.table!.data.data.indexOf(row as never)
|
|
215
|
+
const editButton = this.table!.dom.querySelector(
|
|
176
216
|
`tr[data-index="${rowIndex}"] span.edit-bib`
|
|
177
217
|
)
|
|
178
218
|
if (editButton) {
|
|
179
|
-
editButton.click()
|
|
219
|
+
;(editButton as HTMLElement).click()
|
|
180
220
|
}
|
|
181
221
|
},
|
|
182
222
|
onDelete: row => {
|
|
183
|
-
const bibId = row.cells[0].data
|
|
223
|
+
const bibId = row.cells[0].data as number
|
|
184
224
|
this.deleteBibEntryDialog([bibId])
|
|
185
225
|
}
|
|
186
226
|
})
|
|
187
227
|
this.overviewTable.init()
|
|
188
|
-
this.table = this.overviewTable.table
|
|
189
|
-
this.table.id = "bibliography"
|
|
228
|
+
this.table = this.overviewTable.table as DataTable
|
|
229
|
+
;(this.table as unknown as {id: string}).id = "bibliography"
|
|
190
230
|
this.dtBulk = this.overviewTable.dtBulk
|
|
191
231
|
|
|
192
232
|
this.table.on("datatable.sort", (column, dir) => {
|
|
@@ -200,75 +240,79 @@ export class BibliographyOverview {
|
|
|
200
240
|
* @function setBibCategoryList
|
|
201
241
|
* @param newBibCategories The new categories which will be added to the existing ones.
|
|
202
242
|
*/
|
|
203
|
-
setBibCategoryList(bibCategories) {
|
|
204
|
-
const catSelector = this.menu
|
|
243
|
+
setBibCategoryList(bibCategories: BibCategory[]): void {
|
|
244
|
+
const catSelector = this.menu!.model.content.find(
|
|
205
245
|
menuItem => menuItem.id === "cat_selector"
|
|
206
246
|
)
|
|
207
|
-
catSelector
|
|
208
|
-
|
|
209
|
-
|
|
247
|
+
if (!catSelector) {
|
|
248
|
+
return
|
|
249
|
+
}
|
|
250
|
+
const dropdown = catSelector as {
|
|
251
|
+
content: {type?: string; title?: string; action?: unknown}[]
|
|
252
|
+
}
|
|
253
|
+
dropdown.content = dropdown.content.filter(cat => cat.type !== "category")
|
|
210
254
|
|
|
211
|
-
|
|
255
|
+
dropdown.content = dropdown.content.concat(
|
|
212
256
|
bibCategories.map(cat => ({
|
|
213
257
|
title: cat.category_title,
|
|
214
258
|
type: "category",
|
|
215
|
-
action: _overview => {
|
|
259
|
+
action: (_overview: BibliographyOverview) => {
|
|
216
260
|
const trs = this.dom.querySelectorAll(
|
|
217
261
|
"#bibliography > tbody > tr"
|
|
218
262
|
)
|
|
219
263
|
trs.forEach(tr => {
|
|
264
|
+
const titleEl = tr.querySelector(".fw-data-table-title")
|
|
220
265
|
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
.classList.contains(`cat_${cat.id}`)
|
|
266
|
+
titleEl &&
|
|
267
|
+
titleEl.classList.contains(`cat_${cat.id}`)
|
|
224
268
|
) {
|
|
225
|
-
tr.style.display = ""
|
|
269
|
+
;(tr as HTMLElement).style.display = ""
|
|
226
270
|
} else {
|
|
227
|
-
tr.style.display = "none"
|
|
271
|
+
;(tr as HTMLElement).style.display = "none"
|
|
228
272
|
}
|
|
229
273
|
})
|
|
230
274
|
}
|
|
231
275
|
}))
|
|
232
276
|
)
|
|
233
|
-
this.menu
|
|
277
|
+
this.menu!.update()
|
|
234
278
|
}
|
|
235
279
|
|
|
236
280
|
/** This takes a list of new bib entries and adds them to BibDB and the bibliography table
|
|
237
281
|
* @function updateTable
|
|
238
282
|
*/
|
|
239
|
-
updateTable(ids) {
|
|
283
|
+
updateTable(ids: number[]): void {
|
|
240
284
|
// Remove items that already exist
|
|
241
285
|
this.removeTableRows(ids)
|
|
242
|
-
this.table
|
|
286
|
+
this.table!.insert({data: ids.map(id => this.createTableRow(id))})
|
|
243
287
|
// Redo last sort
|
|
244
|
-
this.table
|
|
288
|
+
this.table!.columns.sort(this.lastSort.column, this.lastSort.dir)
|
|
245
289
|
}
|
|
246
290
|
|
|
247
|
-
createTableRow(id) {
|
|
248
|
-
const bibInfo = this.app.bibDB.db[id]
|
|
291
|
+
createTableRow(id: string | number): (string | number | boolean)[] {
|
|
292
|
+
const bibInfo = this.app.bibDB.db[id as number]
|
|
249
293
|
const bibauthors = bibInfo.fields.author || bibInfo.fields.editor
|
|
250
294
|
const cats = bibInfo.cats.map(cat => `cat_${cat}`)
|
|
251
295
|
return [
|
|
252
|
-
id,
|
|
296
|
+
id as number,
|
|
253
297
|
false, // checkbox
|
|
254
298
|
`<span class="fw-data-table-title ${cats.join(" ")}">
|
|
255
299
|
<i class="fa fa-book"></i>
|
|
256
300
|
<span class="edit-bib fw-link-text fw-searchable" data-id="${id}">
|
|
257
|
-
${bibInfo.fields.title?.length ? escapeText(litToText(bibInfo.fields.title)) : gettext("Untitled")}
|
|
301
|
+
${(bibInfo.fields.title as NodeArray | undefined)?.length ? escapeText(litToText(bibInfo.fields.title as NodeArray)) : gettext("Untitled")}
|
|
258
302
|
</span>
|
|
259
303
|
${bibInfo.entry_key ? `<small class="bib-entry-key">${escapeText(bibInfo.entry_key)}</small>` : ""}
|
|
260
304
|
</span>`, // title
|
|
261
305
|
getBibTypeTitle(bibInfo.bib_type), // sourcetype
|
|
262
|
-
bibauthors ? nameToText(bibauthors) : "", // author
|
|
263
|
-
`<span class="fw-date">${bibInfo.fields.date ? bibInfo.fields.date.replace("/", " ") : ""}</span>`, // published,
|
|
306
|
+
bibauthors ? nameToText(bibauthors as NameDictObject[]) : "", // author
|
|
307
|
+
`<span class="fw-date">${bibInfo.fields.date ? (bibInfo.fields.date as string).replace("/", " ") : ""}</span>`, // published,
|
|
264
308
|
`<span class="delete-bib fw-link-text" data-id="${id}"><i class="fa fa-trash-alt"> </i></span>` // delete icon
|
|
265
309
|
]
|
|
266
310
|
}
|
|
267
311
|
|
|
268
|
-
removeTableRows(ids) {
|
|
269
|
-
const existingRows = this.table
|
|
312
|
+
removeTableRows(ids: number[]): void {
|
|
313
|
+
const existingRows = this.table!.data.data
|
|
270
314
|
.map((row, index) => {
|
|
271
|
-
const id = row.cells[0].data
|
|
315
|
+
const id = row.cells[0].data as number
|
|
272
316
|
if (ids.includes(id)) {
|
|
273
317
|
return index
|
|
274
318
|
} else {
|
|
@@ -278,14 +322,14 @@ export class BibliographyOverview {
|
|
|
278
322
|
.filter(rowIndex => rowIndex !== false)
|
|
279
323
|
|
|
280
324
|
if (existingRows.length) {
|
|
281
|
-
this.table
|
|
325
|
+
this.table!.rows.remove(existingRows as number[])
|
|
282
326
|
}
|
|
283
327
|
}
|
|
284
328
|
|
|
285
329
|
/** Opens a dialog for editing categories.
|
|
286
330
|
* @function editCategoriesDialog
|
|
287
331
|
*/
|
|
288
|
-
editCategoriesDialog() {
|
|
332
|
+
editCategoriesDialog(): void {
|
|
289
333
|
if (this.app.isOffline()) {
|
|
290
334
|
addAlert(
|
|
291
335
|
"info",
|
|
@@ -295,20 +339,23 @@ export class BibliographyOverview {
|
|
|
295
339
|
)
|
|
296
340
|
return
|
|
297
341
|
}
|
|
298
|
-
const buttons = [
|
|
342
|
+
const buttons: DialogButtonSpec[] = [
|
|
299
343
|
{
|
|
300
344
|
text: gettext("Submit"),
|
|
301
345
|
classes: "fw-dark",
|
|
302
346
|
click: () => {
|
|
303
|
-
const cats
|
|
347
|
+
const cats: {ids: number[]; titles: string[]} = {
|
|
348
|
+
ids: [],
|
|
349
|
+
titles: []
|
|
350
|
+
}
|
|
304
351
|
this.dom
|
|
305
352
|
.querySelectorAll("#edit-categories .category-form")
|
|
306
353
|
.forEach(el => {
|
|
307
|
-
const title = el.value.trim()
|
|
354
|
+
const title = (el as HTMLInputElement).value.trim()
|
|
308
355
|
if (title.length) {
|
|
309
356
|
cats.ids.push(
|
|
310
357
|
Number.parseInt(
|
|
311
|
-
el.getAttribute("data-id") || 0
|
|
358
|
+
el.getAttribute("data-id") || "0"
|
|
312
359
|
)
|
|
313
360
|
)
|
|
314
361
|
cats.titles.push(title)
|
|
@@ -349,8 +396,8 @@ export class BibliographyOverview {
|
|
|
349
396
|
* @function deleteBibEntryDialog
|
|
350
397
|
* @param ids Ids of items that are to be deleted.
|
|
351
398
|
*/
|
|
352
|
-
deleteBibEntryDialog(ids) {
|
|
353
|
-
const buttons = [
|
|
399
|
+
deleteBibEntryDialog(ids: number[]): void {
|
|
400
|
+
const buttons: DialogButtonSpec[] = [
|
|
354
401
|
{
|
|
355
402
|
text: gettext("Delete"),
|
|
356
403
|
classes: "fw-dark",
|
|
@@ -375,13 +422,13 @@ export class BibliographyOverview {
|
|
|
375
422
|
}
|
|
376
423
|
|
|
377
424
|
// get IDs of selected bib entries
|
|
378
|
-
getSelected() {
|
|
425
|
+
getSelected(): number[] {
|
|
379
426
|
return Array.from(
|
|
380
427
|
this.dom.querySelectorAll(".entry-select:checked:not(:disabled)")
|
|
381
|
-
).map(el => Number.parseInt(el.getAttribute("data-id")))
|
|
428
|
+
).map(el => Number.parseInt(el.getAttribute("data-id") || ""))
|
|
382
429
|
}
|
|
383
430
|
|
|
384
|
-
activatePlugins() {
|
|
431
|
+
activatePlugins(): Promise<unknown> | void {
|
|
385
432
|
if (this.plugins) {
|
|
386
433
|
// Plugins have been activated already
|
|
387
434
|
return
|
|
@@ -390,18 +437,18 @@ export class BibliographyOverview {
|
|
|
390
437
|
this.plugins = {}
|
|
391
438
|
|
|
392
439
|
return Promise.all(
|
|
393
|
-
|
|
440
|
+
this.bibPlugins.map(([app, plugin]) => {
|
|
394
441
|
if (!this.app.settings.APPS.includes(app)) {
|
|
395
442
|
return Promise.resolve()
|
|
396
443
|
}
|
|
397
444
|
return Promise.all(
|
|
398
445
|
Object.values(plugin).map(pluginExport => {
|
|
399
446
|
if (typeof pluginExport === "function") {
|
|
400
|
-
this.plugins[pluginExport.name] = new pluginExport(
|
|
447
|
+
this.plugins![pluginExport.name] = new pluginExport(
|
|
401
448
|
this
|
|
402
449
|
)
|
|
403
450
|
return (
|
|
404
|
-
this.plugins[pluginExport.name].init() ||
|
|
451
|
+
this.plugins![pluginExport.name].init() ||
|
|
405
452
|
Promise.resolve()
|
|
406
453
|
)
|
|
407
454
|
}
|
|
@@ -415,7 +462,7 @@ export class BibliographyOverview {
|
|
|
415
462
|
/** Initialize the bibliography table and bind interactive parts.
|
|
416
463
|
* @function bibEvents
|
|
417
464
|
*/
|
|
418
|
-
bindEvents() {
|
|
465
|
+
bindEvents(): void {
|
|
419
466
|
this.dom.addEventListener("click", event =>
|
|
420
467
|
this.handleActivation(event)
|
|
421
468
|
)
|
|
@@ -425,58 +472,77 @@ export class BibliographyOverview {
|
|
|
425
472
|
|
|
426
473
|
// Allow pasting of bibtex data.
|
|
427
474
|
this.dom.addEventListener("paste", event => {
|
|
428
|
-
if (event.target.nodeName === "INPUT") {
|
|
475
|
+
if ((event.target as Element).nodeName === "INPUT") {
|
|
429
476
|
// We are inside of an input element, cancel.
|
|
430
477
|
return false
|
|
431
478
|
}
|
|
479
|
+
if (!event.clipboardData) {
|
|
480
|
+
return false
|
|
481
|
+
}
|
|
432
482
|
const text = event.clipboardData.getData("text")
|
|
433
483
|
return this.getBibtex(text)
|
|
434
484
|
})
|
|
435
485
|
|
|
436
486
|
// The two drag events are needed to allow dropping
|
|
437
487
|
this.dom.addEventListener("dragover", event => {
|
|
438
|
-
if (
|
|
488
|
+
if (
|
|
489
|
+
event.dataTransfer &&
|
|
490
|
+
event.dataTransfer.types.includes("text/plain")
|
|
491
|
+
) {
|
|
439
492
|
event.preventDefault()
|
|
440
493
|
}
|
|
441
494
|
})
|
|
442
495
|
|
|
443
496
|
this.dom.addEventListener("dragenter", event => {
|
|
444
|
-
if (
|
|
497
|
+
if (
|
|
498
|
+
event.dataTransfer &&
|
|
499
|
+
event.dataTransfer.types.includes("text/plain")
|
|
500
|
+
) {
|
|
445
501
|
event.preventDefault()
|
|
446
502
|
}
|
|
447
503
|
})
|
|
448
504
|
|
|
449
505
|
// Allow dropping of bibtex data
|
|
450
506
|
this.dom.addEventListener("drop", event => {
|
|
451
|
-
if (event.target.nodeName === "INPUT") {
|
|
507
|
+
if ((event.target as Element).nodeName === "INPUT") {
|
|
452
508
|
// We are inside of an input element, cancel.
|
|
453
509
|
return false
|
|
454
510
|
}
|
|
511
|
+
if (!event.dataTransfer) {
|
|
512
|
+
return false
|
|
513
|
+
}
|
|
455
514
|
const text = fixUTF8(event.dataTransfer.getData("text"))
|
|
456
515
|
return this.getBibtex(text)
|
|
457
516
|
})
|
|
458
517
|
}
|
|
459
518
|
|
|
460
|
-
handleActivation(event) {
|
|
519
|
+
handleActivation(event: Event): void {
|
|
461
520
|
if (!isActivationEvent(event)) {
|
|
462
521
|
return
|
|
463
522
|
}
|
|
464
|
-
const el = {}
|
|
523
|
+
const el: {target?: Element | null} = {}
|
|
465
524
|
switch (true) {
|
|
466
525
|
case findTarget(event, ".delete-bib", el): {
|
|
467
|
-
const bibId = Number.parseInt(
|
|
526
|
+
const bibId = Number.parseInt(
|
|
527
|
+
(el.target as HTMLElement).dataset.id || ""
|
|
528
|
+
)
|
|
468
529
|
this.deleteBibEntryDialog([bibId])
|
|
469
530
|
break
|
|
470
531
|
}
|
|
471
532
|
case findTarget(event, ".edit-bib", el): {
|
|
472
|
-
const bibId = Number.parseInt(
|
|
533
|
+
const bibId = Number.parseInt(
|
|
534
|
+
(el.target as HTMLElement).dataset.id || ""
|
|
535
|
+
)
|
|
473
536
|
import("../form/index.js").then(({BibEntryForm}) => {
|
|
474
537
|
const form = new BibEntryForm(
|
|
475
538
|
this.app.bibDB,
|
|
476
539
|
this.app,
|
|
477
540
|
bibId
|
|
478
541
|
)
|
|
479
|
-
form.init().then(idTranslations => {
|
|
542
|
+
form.init().then((idTranslations: IdTranslation[] | void) => {
|
|
543
|
+
if (!idTranslations) {
|
|
544
|
+
return
|
|
545
|
+
}
|
|
480
546
|
const ids = idTranslations.map(idTrans => idTrans[1])
|
|
481
547
|
return this.updateTable(ids)
|
|
482
548
|
})
|
|
@@ -484,7 +550,10 @@ export class BibliographyOverview {
|
|
|
484
550
|
break
|
|
485
551
|
}
|
|
486
552
|
case findTarget(event, ".fw-add-input", el): {
|
|
487
|
-
const itemEl = el.target.closest(".fw-list-input")
|
|
553
|
+
const itemEl = (el.target as HTMLElement).closest(".fw-list-input")
|
|
554
|
+
if (!itemEl) {
|
|
555
|
+
break
|
|
556
|
+
}
|
|
488
557
|
if (!itemEl.nextElementSibling) {
|
|
489
558
|
itemEl.insertAdjacentHTML(
|
|
490
559
|
"afterend",
|
|
@@ -496,7 +565,7 @@ export class BibliographyOverview {
|
|
|
496
565
|
</tr>`
|
|
497
566
|
)
|
|
498
567
|
} else {
|
|
499
|
-
itemEl.parentElement
|
|
568
|
+
itemEl.parentElement!.removeChild(itemEl)
|
|
500
569
|
}
|
|
501
570
|
break
|
|
502
571
|
}
|
|
@@ -506,7 +575,7 @@ export class BibliographyOverview {
|
|
|
506
575
|
}
|
|
507
576
|
|
|
508
577
|
// find bibtex in pasted or dropped data.
|
|
509
|
-
getBibtex(text) {
|
|
578
|
+
getBibtex(text: string): boolean {
|
|
510
579
|
import("../import/index.js").then(({BibliographyImporter}) => {
|
|
511
580
|
const importer = new BibliographyImporter(
|
|
512
581
|
text,
|
|
@@ -519,30 +588,30 @@ export class BibliographyOverview {
|
|
|
519
588
|
return true
|
|
520
589
|
}
|
|
521
590
|
|
|
522
|
-
saveCategories(cats) {
|
|
591
|
+
saveCategories(cats: {ids: number[]; titles: string[]}): void {
|
|
523
592
|
this.app.bibDB
|
|
524
593
|
.saveCategories(cats)
|
|
525
594
|
.then(bibCats => this.setBibCategoryList(bibCats))
|
|
526
595
|
}
|
|
527
596
|
|
|
528
|
-
deleteBibEntries(ids) {
|
|
597
|
+
deleteBibEntries(ids: number[]): void {
|
|
529
598
|
this.app.bibDB
|
|
530
599
|
.deleteBibEntries(ids)
|
|
531
600
|
.then(ids => this.removeTableRows(ids))
|
|
532
601
|
}
|
|
533
602
|
|
|
534
|
-
close() {
|
|
603
|
+
close(): void {
|
|
535
604
|
if (this.table) {
|
|
536
605
|
this.table.destroy()
|
|
537
|
-
this.table =
|
|
606
|
+
this.table = undefined
|
|
538
607
|
}
|
|
539
608
|
if (this.dtBulk) {
|
|
540
609
|
this.dtBulk.destroy()
|
|
541
|
-
this.dtBulk =
|
|
610
|
+
this.dtBulk = undefined
|
|
542
611
|
}
|
|
543
612
|
if (this.menu) {
|
|
544
613
|
this.menu.destroy()
|
|
545
|
-
this.menu =
|
|
614
|
+
this.menu = undefined
|
|
546
615
|
}
|
|
547
616
|
}
|
|
548
617
|
}
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import {BibLatexFileExporter} from "../export/index.js"
|
|
2
2
|
import {BibliographyFileImportDialog} from "../import/index.js"
|
|
3
|
+
import type {IdTranslation} from "../types/biblio.js"
|
|
4
|
+
import type {BibliographyOverview} from "./index.js"
|
|
3
5
|
|
|
4
6
|
export const bulkMenuModel = () => ({
|
|
5
7
|
content: [
|
|
6
8
|
{
|
|
7
9
|
title: gettext("Delete selected"),
|
|
8
10
|
tooltip: gettext("Delete selected bibliography entries."),
|
|
9
|
-
action: overview => {
|
|
11
|
+
action: (overview: BibliographyOverview) => {
|
|
10
12
|
const ids = overview
|
|
11
13
|
.getSelected()
|
|
12
|
-
.map(id => Number.parseInt(id))
|
|
14
|
+
.map(id => Number.parseInt(String(id)))
|
|
13
15
|
if (ids.length) {
|
|
14
16
|
overview.deleteBibEntryDialog(ids)
|
|
15
17
|
}
|
|
16
18
|
},
|
|
17
|
-
disabled: overview =>
|
|
19
|
+
disabled: (overview: BibliographyOverview) =>
|
|
18
20
|
!overview.getSelected().length || overview.app.isOffline()
|
|
19
21
|
},
|
|
20
22
|
{
|
|
21
23
|
title: gettext("Export selected"),
|
|
22
24
|
tooltip: gettext("Export selected bibliography entries."),
|
|
23
|
-
action: overview => {
|
|
25
|
+
action: (overview: BibliographyOverview) => {
|
|
24
26
|
const ids = overview.getSelected()
|
|
25
27
|
if (ids.length) {
|
|
26
28
|
const exporter = new BibLatexFileExporter(
|
|
@@ -30,7 +32,7 @@ export const bulkMenuModel = () => ({
|
|
|
30
32
|
exporter.init()
|
|
31
33
|
}
|
|
32
34
|
},
|
|
33
|
-
disabled: overview =>
|
|
35
|
+
disabled: (overview: BibliographyOverview) =>
|
|
34
36
|
!overview.getSelected().length || overview.app.isOffline()
|
|
35
37
|
}
|
|
36
38
|
]
|
|
@@ -45,11 +47,11 @@ export const menuModel = () => ({
|
|
|
45
47
|
content: [
|
|
46
48
|
{
|
|
47
49
|
title: gettext("All categories"),
|
|
48
|
-
action: _overview => {
|
|
50
|
+
action: (_overview: BibliographyOverview) => {
|
|
49
51
|
const trs = document.querySelectorAll(
|
|
50
52
|
"#bibliography > tbody > tr"
|
|
51
53
|
)
|
|
52
|
-
trs.forEach(tr => (tr.style.display = ""))
|
|
54
|
+
trs.forEach(tr => ((tr as HTMLElement).style.display = ""))
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
],
|
|
@@ -59,20 +61,23 @@ export const menuModel = () => ({
|
|
|
59
61
|
type: "text",
|
|
60
62
|
title: gettext("Edit categories"),
|
|
61
63
|
keys: "Alt-e",
|
|
62
|
-
action: overview => overview.editCategoriesDialog(),
|
|
64
|
+
action: (overview: BibliographyOverview) => overview.editCategoriesDialog(),
|
|
63
65
|
order: 2
|
|
64
66
|
},
|
|
65
67
|
{
|
|
66
68
|
type: "text",
|
|
67
69
|
title: gettext("Register new source"),
|
|
68
70
|
keys: "Alt-n",
|
|
69
|
-
action: overview => {
|
|
71
|
+
action: (overview: BibliographyOverview) => {
|
|
70
72
|
import("../form/index.js").then(({BibEntryForm}) => {
|
|
71
73
|
const form = new BibEntryForm(
|
|
72
74
|
overview.app.bibDB,
|
|
73
75
|
overview.app
|
|
74
76
|
)
|
|
75
|
-
form.init().then(idTranslations => {
|
|
77
|
+
form.init().then((idTranslations: IdTranslation[] | void) => {
|
|
78
|
+
if (!idTranslations) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
76
81
|
const ids = idTranslations.map(idTrans => idTrans[1])
|
|
77
82
|
return overview.updateTable(ids)
|
|
78
83
|
})
|
|
@@ -84,7 +89,7 @@ export const menuModel = () => ({
|
|
|
84
89
|
type: "text",
|
|
85
90
|
title: gettext("Import bibliography"),
|
|
86
91
|
keys: "Alt-u",
|
|
87
|
-
action: overview => {
|
|
92
|
+
action: (overview: BibliographyOverview) => {
|
|
88
93
|
const fileImporter = new BibliographyFileImportDialog(
|
|
89
94
|
overview.app.bibDB,
|
|
90
95
|
ids => overview.updateTable(ids),
|
|
@@ -99,7 +104,8 @@ export const menuModel = () => ({
|
|
|
99
104
|
icon: "search",
|
|
100
105
|
title: gettext("Search bibliography"),
|
|
101
106
|
keys: "Alt-s",
|
|
102
|
-
input: (overview, text) =>
|
|
107
|
+
input: (overview: BibliographyOverview, text: string) =>
|
|
108
|
+
overview.table!.search(text),
|
|
103
109
|
order: 5
|
|
104
110
|
}
|
|
105
111
|
]
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {escapeText} from "fwtoolkit"
|
|
2
|
+
import type {BibCategory} from "../types/biblio.js"
|
|
2
3
|
|
|
3
4
|
/** A template for each category in the category list edit of the bibliography categories list. */
|
|
4
|
-
const categoryFormsTemplate = ({categories}) =>
|
|
5
|
+
const categoryFormsTemplate = ({categories}: {categories: BibCategory[]}) =>
|
|
5
6
|
`${categories
|
|
6
7
|
.map(
|
|
7
8
|
cat =>
|
|
@@ -22,7 +23,7 @@ const categoryFormsTemplate = ({categories}) =>
|
|
|
22
23
|
</tr>`
|
|
23
24
|
|
|
24
25
|
/** A template for the editing of bibliography categories list. */
|
|
25
|
-
export const editCategoriesTemplate = ({categories}) =>
|
|
26
|
+
export const editCategoriesTemplate = ({categories}: {categories: BibCategory[]}) =>
|
|
26
27
|
`<table id="editCategoryList" class="fw-dialog-table">
|
|
27
28
|
<tbody>
|
|
28
29
|
${categoryFormsTemplate({categories})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const plugins: unknown[] = []
|