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