fwtoolkit 0.1.0-alpha.6 → 0.1.0-beta.1

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.
Files changed (122) hide show
  1. package/css/alerts.css +7 -0
  2. package/css/dialog.css +62 -0
  3. package/css/overview_menu.css +7 -0
  4. package/dist/basic.d.ts +49 -36
  5. package/dist/basic.d.ts.map +1 -1
  6. package/dist/basic.js +58 -39
  7. package/dist/basic.js.map +1 -1
  8. package/dist/blob.d.ts +1 -1
  9. package/dist/blob.d.ts.map +1 -1
  10. package/dist/blob.js +0 -1
  11. package/dist/blob.js.map +1 -1
  12. package/dist/content_menu.d.ts +63 -20
  13. package/dist/content_menu.d.ts.map +1 -1
  14. package/dist/content_menu.js +23 -20
  15. package/dist/content_menu.js.map +1 -1
  16. package/dist/datatable_bulk.d.ts +34 -6
  17. package/dist/datatable_bulk.d.ts.map +1 -1
  18. package/dist/datatable_bulk.js +4 -5
  19. package/dist/datatable_bulk.js.map +1 -1
  20. package/dist/dialog.d.ts +82 -7
  21. package/dist/dialog.d.ts.map +1 -1
  22. package/dist/dialog.js +21 -16
  23. package/dist/dialog.js.map +1 -1
  24. package/dist/events.d.ts +1 -1
  25. package/dist/events.d.ts.map +1 -1
  26. package/dist/events.js +3 -3
  27. package/dist/events.js.map +1 -1
  28. package/dist/faq_dialog.d.ts +13 -4
  29. package/dist/faq_dialog.d.ts.map +1 -1
  30. package/dist/faq_dialog.js +4 -2
  31. package/dist/faq_dialog.js.map +1 -1
  32. package/dist/file/dialog.d.ts +33 -13
  33. package/dist/file/dialog.d.ts.map +1 -1
  34. package/dist/file/dialog.js +6 -8
  35. package/dist/file/dialog.js.map +1 -1
  36. package/dist/file/index.d.ts.map +1 -1
  37. package/dist/file/index.js +0 -1
  38. package/dist/file/index.js.map +1 -1
  39. package/dist/file/new_folder_dialog.d.ts +5 -2
  40. package/dist/file/new_folder_dialog.d.ts.map +1 -1
  41. package/dist/file/new_folder_dialog.js +1 -2
  42. package/dist/file/new_folder_dialog.js.map +1 -1
  43. package/dist/file/selector.d.ts +47 -14
  44. package/dist/file/selector.d.ts.map +1 -1
  45. package/dist/file/selector.js +11 -9
  46. package/dist/file/selector.js.map +1 -1
  47. package/dist/file/templates.d.ts +1 -1
  48. package/dist/file/templates.d.ts.map +1 -1
  49. package/dist/file/templates.js +0 -1
  50. package/dist/file/templates.js.map +1 -1
  51. package/dist/file/tools.d.ts +4 -4
  52. package/dist/file/tools.d.ts.map +1 -1
  53. package/dist/file/tools.js +4 -4
  54. package/dist/file/tools.js.map +1 -1
  55. package/dist/focus.d.ts +1 -1
  56. package/dist/focus.d.ts.map +1 -1
  57. package/dist/focus.js +5 -5
  58. package/dist/focus.js.map +1 -1
  59. package/dist/index.d.ts +0 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +0 -3
  62. package/dist/index.js.map +1 -1
  63. package/dist/network.d.ts +19 -7
  64. package/dist/network.d.ts.map +1 -1
  65. package/dist/network.js +15 -12
  66. package/dist/network.js.map +1 -1
  67. package/dist/overview_menu.d.ts +77 -18
  68. package/dist/overview_menu.d.ts.map +1 -1
  69. package/dist/overview_menu.js +54 -35
  70. package/dist/overview_menu.js.map +1 -1
  71. package/dist/settings.d.ts +7 -2
  72. package/dist/settings.d.ts.map +1 -1
  73. package/dist/settings.js +0 -1
  74. package/dist/settings.js.map +1 -1
  75. package/dist/user.d.ts +8 -2
  76. package/dist/user.d.ts.map +1 -1
  77. package/dist/user.js +1 -2
  78. package/dist/user.js.map +1 -1
  79. package/dist/worker.d.ts +1 -1
  80. package/dist/worker.d.ts.map +1 -1
  81. package/dist/worker.js +1 -2
  82. package/dist/worker.js.map +1 -1
  83. package/dist/ws.d.ts +59 -25
  84. package/dist/ws.d.ts.map +1 -1
  85. package/dist/ws.js +19 -15
  86. package/dist/ws.js.map +1 -1
  87. package/package.json +2 -1
  88. package/src/basic.ts +136 -69
  89. package/src/blob.ts +1 -2
  90. package/src/content_menu.ts +127 -44
  91. package/src/datatable_bulk.ts +72 -35
  92. package/src/dialog.ts +156 -61
  93. package/src/diff-dom.d.ts +16 -0
  94. package/src/events.ts +3 -3
  95. package/src/faq_dialog.ts +25 -11
  96. package/src/file/dialog.ts +48 -14
  97. package/src/file/index.ts +0 -1
  98. package/src/file/new_folder_dialog.ts +7 -5
  99. package/src/file/selector.ts +86 -36
  100. package/src/file/templates.ts +2 -3
  101. package/src/file/tools.ts +17 -8
  102. package/src/focus.ts +11 -13
  103. package/src/global.d.ts +11 -4
  104. package/src/index.ts +0 -3
  105. package/src/network.ts +58 -20
  106. package/src/overview_menu.ts +183 -109
  107. package/src/settings.ts +9 -4
  108. package/src/user.ts +10 -5
  109. package/src/w3c-keyname.d.ts +3 -0
  110. package/src/worker.ts +1 -2
  111. package/src/ws.ts +115 -50
  112. package/css/ui_dialogs.css +0 -144
  113. package/dist/templates.d.ts +0 -7
  114. package/dist/templates.d.ts.map +0 -1
  115. package/dist/templates.js +0 -43
  116. package/dist/templates.js.map +0 -1
  117. package/dist/user_util.d.ts +0 -7
  118. package/dist/user_util.d.ts.map +0 -1
  119. package/dist/user_util.js +0 -19
  120. package/dist/user_util.js.map +0 -1
  121. package/src/templates.ts +0 -43
  122. package/src/user_util.ts +0 -17
package/src/settings.ts CHANGED
@@ -1,7 +1,12 @@
1
- // @ts-nocheck
2
- let _settings = null
1
+ export interface Settings {
2
+ apiUrl: (url: string) => string
3
+ getCsrfToken: () => string
4
+ [key: string]: unknown
5
+ }
6
+
7
+ let _settings: Settings | null = null
3
8
 
4
- export function initSettings(rawSettings) {
9
+ export function initSettings(rawSettings: Settings): void {
5
10
  if (_settings) {
6
11
  throw new Error("Settings already initialized")
7
12
  }
@@ -9,7 +14,7 @@ export function initSettings(rawSettings) {
9
14
  _settings = Object.freeze({...rawSettings})
10
15
  }
11
16
 
12
- export function getSettings() {
17
+ export function getSettings(): Settings {
13
18
  if (!_settings) {
14
19
  throw new Error(
15
20
  "App settings not initialized. Call initSettings() first."
package/src/user.ts CHANGED
@@ -1,7 +1,6 @@
1
- // @ts-nocheck
2
1
  import {post} from "./network.js"
3
2
 
4
- export const setLanguage = (_config, language) =>
3
+ export const setLanguage = (_config: unknown, language: string): Promise<unknown> =>
5
4
  post("/api/i18n/setlang/", {language}).then(() => {
6
5
  // We delete the network cache as this contains the JS
7
6
  // translations.
@@ -13,9 +12,9 @@ export const setLanguage = (_config, language) =>
13
12
  })
14
13
  })
15
14
 
16
- const COLOR_CACHE = {}
15
+ const COLOR_CACHE: Record<string, string> = {}
17
16
 
18
- const userColor = string => {
17
+ const userColor = (string: string): string => {
19
18
  // Source https://gist.github.com/0x263b/2bdd90886c2036a1ad5bcf06d6e6fb37
20
19
  if (string.length === 0) {
21
20
  return "rgb(0,0,0)"
@@ -35,8 +34,14 @@ const userColor = string => {
35
34
  return COLOR_CACHE[string]
36
35
  }
37
36
 
37
+ interface AvatarUser {
38
+ username?: string
39
+ name?: string
40
+ avatar?: string
41
+ }
42
+
38
43
  /** A template for the default round avatar view. */
39
- export const avatarTemplate = ({user}) => {
44
+ export const avatarTemplate = ({user}: {user: AvatarUser}): string => {
40
45
  const name = user.username || user.name || "A"
41
46
  if (user.avatar) {
42
47
  return `<img class="fw-avatar" src="${user.avatar}" alt="${name}">`
@@ -0,0 +1,3 @@
1
+ declare module "w3c-keyname" {
2
+ export function keyName(event: KeyboardEvent): string
3
+ }
package/src/worker.ts CHANGED
@@ -1,7 +1,6 @@
1
- // @ts-nocheck
2
1
  /* allows cross domain web workers */
3
2
  /* Taken from https://benohead.com/cross-domain-cross-browser-web-workers/ */
4
- export const makeWorker = workerUrl => {
3
+ export const makeWorker = (workerUrl: string): Worker => {
5
4
  const a = document.createElement("a")
6
5
  a.href = workerUrl // turn into absolute URL if needed.
7
6
  const blob = new Blob([`importScripts("${a.href}")`], {
package/src/ws.ts CHANGED
@@ -1,7 +1,67 @@
1
- // @ts-nocheck
1
+ export interface WebSocketMessage {
2
+ type?: string
3
+ s?: number
4
+ c?: number
5
+ base?: string
6
+ from?: number
7
+ [key: string]: unknown
8
+ }
9
+
10
+ export type GetMessage = () => WebSocketMessage | false
11
+
12
+ export interface WebSocketConnectorOptions {
13
+ base?: string
14
+ path?: string
15
+ appLoaded?: () => boolean
16
+ anythingToSend?: () => boolean
17
+ messagesElement?: () => HTMLElement | false | null
18
+ initialMessage?: () => WebSocketMessage
19
+ resubScribed?: () => void
20
+ restartMessage?: () => WebSocketMessage
21
+ warningNotAllSent?: string
22
+ infoDisconnected?: string
23
+ receiveData?: (data: WebSocketMessage) => void
24
+ failedAuth?: () => void
25
+ }
26
+
27
+ interface MessageTracker {
28
+ server: number
29
+ client: number
30
+ lastTen: WebSocketMessage[]
31
+ }
32
+
2
33
  /* Sets up communicating with server (retrieving document, saving, collaboration, etc.).
3
34
  */
4
35
  export class WebSocketConnector {
36
+ base: string
37
+ path: string
38
+ appLoaded: () => boolean
39
+ anythingToSend: () => boolean
40
+ messagesElement: () => HTMLElement | false | null
41
+ initialMessage: () => WebSocketMessage
42
+ resubScribed: () => void
43
+ restartMessage: () => WebSocketMessage
44
+ warningNotAllSent: string
45
+ infoDisconnected: string
46
+ receiveData: (data: WebSocketMessage) => void
47
+ failedAuth: () => void
48
+
49
+ messages: MessageTracker
50
+ messagesToSend: GetMessage[]
51
+ oldMessages: GetMessage[]
52
+
53
+ online: boolean
54
+ connected: boolean
55
+ connectionCount: number
56
+ recentlySent: boolean
57
+ listeners: Record<string, (event: Event) => void>
58
+
59
+ ws: WebSocket | undefined
60
+
61
+ //heartbeat
62
+ pingTimer: number | false
63
+ pongTimer: number | false
64
+
5
65
  constructor({
6
66
  base = "", // needs to be specified
7
67
  path = "", // needs to be specified
@@ -13,11 +73,11 @@ export class WebSocketConnector {
13
73
  restartMessage = () => ({type: "restart"}), // Too many messages have been lost and we need to restart
14
74
  warningNotAllSent = gettext("Warning! Some data is unsaved"), // Info to show while disconnected WITH unsaved data
15
75
  infoDisconnected = gettext("Disconnected. Attempting to reconnect..."), // Info to show while disconnected WITHOUT unsaved data
16
- receiveData = _data => {},
76
+ receiveData = () => {},
17
77
  failedAuth = () => {
18
78
  window.location.href = "/"
19
79
  }
20
- }) {
80
+ }: WebSocketConnectorOptions = {}) {
21
81
  this.base = base
22
82
  this.path = path
23
83
  this.appLoaded = appLoaded
@@ -48,31 +108,32 @@ export class WebSocketConnector {
48
108
  //heartbeat
49
109
  this.pingTimer = false
50
110
  this.pongTimer = false
111
+
112
+ this.messages = {
113
+ server: 0,
114
+ client: 0,
115
+ lastTen: []
116
+ }
51
117
  }
52
118
 
53
- init() {
119
+ init(): void {
54
120
  this.createWSConnection()
55
121
 
56
122
  // Close the socket manually for now when the connection is lost. Sometimes the socket isn't closed on disconnection.
57
- this.listeners.onOffline = _event => this.ws.close()
123
+ this.listeners.onOffline = () => this.ws!.close()
58
124
  window.addEventListener("offline", this.listeners.onOffline)
59
125
  }
60
126
 
61
- goOffline() {
127
+ goOffline(): void {
62
128
  // Simulate offline mode due to lack of ways of doing this in Chrome/Firefox
63
129
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1421357
64
130
  // https://bugs.chromium.org/p/chromium/issues/detail?id=423246
65
131
  this.online = false
66
132
  this.connected = false
67
- this.ws.close()
133
+ this.ws!.close()
68
134
  }
69
135
 
70
- goOnline() {
71
- // Reconnect from offline mode
72
- this.online = true
73
- }
74
-
75
- close() {
136
+ close(): void {
76
137
  if (this.ws) {
77
138
  this.ws.onclose = () => {}
78
139
  this.ws.close()
@@ -80,14 +141,14 @@ export class WebSocketConnector {
80
141
  window.removeEventListener("offline", this.listeners.onOffline)
81
142
  }
82
143
 
83
- createWSConnection() {
144
+ createWSConnection(): void {
84
145
  // Messages object used to ensure that data is received in right order.
85
146
  this.messages = {
86
147
  server: 0,
87
148
  client: 0,
88
149
  lastTen: []
89
150
  }
90
- let url
151
+ let url: string
91
152
  if (this.online) {
92
153
  if (this.base.startsWith("/")) {
93
154
  url = this.base + this.path
@@ -113,7 +174,7 @@ export class WebSocketConnector {
113
174
  this.ws.onclose = () => this.onclose()
114
175
  }
115
176
 
116
- waitForWS() {
177
+ waitForWS(): Promise<void> {
117
178
  return new Promise((resolve, reject) => {
118
179
  const checkState = () => {
119
180
  if (!this.ws) {
@@ -138,22 +199,22 @@ export class WebSocketConnector {
138
199
  })
139
200
  }
140
201
 
141
- onmessage(event) {
142
- const data = JSON.parse(event.data)
202
+ onmessage(event: MessageEvent): void {
203
+ const data = JSON.parse(event.data) as WebSocketMessage
143
204
  const expectedServer = this.messages.server + 1
144
205
  if (data.type === "request_resend") {
145
- this.resend_messages(data.from)
206
+ this.resend_messages(data.from!)
146
207
  } else if (data.type === "pong") {
147
208
  this.heartbeat()
148
- } else if (data.s < expectedServer) {
209
+ } else if ((data.s as number) < expectedServer) {
149
210
  // Receive a message already received at least once. Ignore.
150
211
  return
151
- } else if (data.s > expectedServer) {
212
+ } else if ((data.s as number) > expectedServer) {
152
213
  // Messages from the server have been lost.
153
214
  // Request resend.
154
215
  this.waitForWS()
155
216
  .then(() =>
156
- this.ws.send(
217
+ this.ws!.send(
157
218
  JSON.stringify({
158
219
  type: "request_resend",
159
220
  from: this.messages.server
@@ -167,27 +228,27 @@ export class WebSocketConnector {
167
228
  this.messages.server = expectedServer
168
229
  if (data.c === this.messages.client) {
169
230
  this.receive(data)
170
- } else if (data.c < this.messages.client) {
231
+ } else if ((data.c as number) < this.messages.client) {
171
232
  // We have received all server messages, but the server seems
172
233
  // to have missed some of the client's messages. They could
173
234
  // have been sent simultaneously.
174
235
  // The server wins over the client in this case.
175
236
  this.waitForWS().then(() => {
176
- const clientDifference = this.messages.client - data.c
177
- this.messages.client = data.c
237
+ const clientDifference = this.messages.client - (data.c as number)
238
+ this.messages.client = data.c as number
178
239
  if (clientDifference > this.messages.lastTen.length) {
179
240
  // We cannot fix the situation
180
241
  this.send(this.restartMessage)
181
242
  return
182
243
  }
183
- this.messages["lastTen"]
244
+ this.messages.lastTen
184
245
  .slice(0 - clientDifference)
185
246
  .forEach(data => {
186
247
  this.messages.client += 1
187
248
  data.c = this.messages.client
188
249
  data.s = this.messages.server
189
250
 
190
- this.ws.send(JSON.stringify(data))
251
+ this.ws!.send(JSON.stringify(data))
191
252
  })
192
253
  this.receive(data)
193
254
  })
@@ -195,7 +256,7 @@ export class WebSocketConnector {
195
256
  }
196
257
  }
197
258
 
198
- onclose() {
259
+ onclose(): void {
199
260
  this.connected = false
200
261
  window.setTimeout(() => {
201
262
  this.createWSConnection()
@@ -215,7 +276,7 @@ export class WebSocketConnector {
215
276
  }
216
277
  }
217
278
 
218
- open() {
279
+ open(): void {
219
280
  const messagesElement = this.messagesElement()
220
281
  if (messagesElement) {
221
282
  messagesElement.innerHTML = ""
@@ -230,19 +291,19 @@ export class WebSocketConnector {
230
291
  this.send(() => message)
231
292
  }
232
293
 
233
- subscribed() {
294
+ subscribed(): void {
234
295
  if (this.connectionCount > 1) {
235
296
  this.resubScribed()
236
297
  }
237
298
  while (this.oldMessages.length > 0) {
238
- this.send(this.oldMessages.shift())
299
+ this.send(this.oldMessages.shift()!)
239
300
  }
240
301
  }
241
302
 
242
303
  /** Sends data to server or keeps it in a list if currently offline. */
243
- send(getData, timer = 80) {
244
- if (this.connected && this.ws.readyState !== this.ws.OPEN) {
245
- this.ws.close()
304
+ send(getData: GetMessage, timer = 80): void {
305
+ if (this.connected && this.ws!.readyState !== this.ws!.OPEN) {
306
+ this.ws!.close()
246
307
  return
247
308
  }
248
309
  if (this.connected && !this.recentlySent) {
@@ -255,11 +316,11 @@ export class WebSocketConnector {
255
316
  data.c = this.messages.client
256
317
  data.s = this.messages.server
257
318
  this.messages.lastTen.push(data)
258
- this.messages.lastTen = this.messages["lastTen"].slice(-10)
319
+ this.messages.lastTen = this.messages.lastTen.slice(-10)
259
320
 
260
321
  this.waitForWS()
261
322
  .then(() => {
262
- this.ws.send(JSON.stringify(data))
323
+ this.ws!.send(JSON.stringify(data))
263
324
  this.setRecentlySentTimer(timer)
264
325
  })
265
326
  .catch(() => {
@@ -275,20 +336,20 @@ export class WebSocketConnector {
275
336
  }
276
337
  }
277
338
 
278
- setRecentlySentTimer(timer) {
339
+ setRecentlySentTimer(timer: number): void {
279
340
  this.recentlySent = true
280
341
  window.setTimeout(() => {
281
342
  this.recentlySent = false
282
343
  const oldMessages = this.messagesToSend
283
344
  this.messagesToSend = []
284
345
  while (oldMessages.length > 0) {
285
- const getData = oldMessages.shift()
346
+ const getData = oldMessages.shift()!
286
347
  this.send(getData, Math.min(timer * 1.2, 10000))
287
348
  }
288
349
  }, timer)
289
350
  }
290
351
 
291
- resend_messages(from) {
352
+ resend_messages(from: number): Promise<void> {
292
353
  return this.waitForWS()
293
354
  .then(() => {
294
355
  const toSend = this.messages.client - from
@@ -302,7 +363,7 @@ export class WebSocketConnector {
302
363
  this.messages.client += 1
303
364
  data.c = this.messages.client
304
365
  data.s = this.messages.server
305
- this.ws.send(JSON.stringify(data))
366
+ this.ws!.send(JSON.stringify(data))
306
367
  })
307
368
  })
308
369
  .catch(() => {
@@ -311,10 +372,10 @@ export class WebSocketConnector {
311
372
  })
312
373
  }
313
374
 
314
- receive(data) {
375
+ receive(data: WebSocketMessage): void {
315
376
  switch (data.type) {
316
377
  case "redirect":
317
- this.base = data.base
378
+ this.base = data.base as string
318
379
  break
319
380
  case "welcome":
320
381
  this.open()
@@ -332,15 +393,19 @@ export class WebSocketConnector {
332
393
  }
333
394
  }
334
395
 
335
- heartbeat() {
336
- clearTimeout(this.pingTimer)
337
- clearTimeout(this.pongTimer)
338
- this.pingTimer = setTimeout(() => {
396
+ heartbeat(): void {
397
+ if (this.pingTimer !== false) {
398
+ clearTimeout(this.pingTimer)
399
+ }
400
+ if (this.pongTimer !== false) {
401
+ clearTimeout(this.pongTimer)
402
+ }
403
+ this.pingTimer = window.setTimeout(() => {
339
404
  // Don't send ping if WebSocket is not open
340
- if (this.ws.readyState === this.ws.OPEN) {
341
- this.ws.send('{"type": "ping"}')
342
- this.pongTimer = setTimeout(() => {
343
- this.listeners.onOffline()
405
+ if (this.ws!.readyState === this.ws!.OPEN) {
406
+ this.ws!.send('{"type": "ping"}')
407
+ this.pongTimer = window.setTimeout(() => {
408
+ this.listeners.onOffline(new Event("offline"))
344
409
  }, 10000)
345
410
  }
346
411
  }, 60000)
@@ -1,144 +0,0 @@
1
- .ui-widget-overlay {
2
- position: fixed;
3
- left: 0;
4
- top: 0;
5
- width: 100%;
6
- height: 100%;
7
- background-color: rgb(var(--overlay-color));
8
- z-index: 100;
9
- backdrop-filter: blur(2px);
10
- }
11
-
12
- .ui-widget-overlay.no-blur {
13
- backdrop-filter: none;
14
- }
15
-
16
- .ui-dialog {
17
- position: absolute;
18
- padding: 19px;
19
- background-color: var(--cs-light-background);
20
- border: solid 1px var(--cs-light-border);
21
- box-shadow: 0 0 10px var(--cs-light-box-shadow);
22
- overflow: hidden;
23
- border-radius: 4px;
24
- font-size: 14px;
25
- outline: 0;
26
- z-index: 1000; /* Ensure dialog stays on top */
27
- user-select: none; /* Prevent interaction with background content */
28
- }
29
-
30
- .ui-dialog-titlebar {
31
- position: relative;
32
- padding: 0;
33
- }
34
-
35
- .ui-dialog-title {
36
- font-size: 16px;
37
- font-weight: 700;
38
- text-transform: none;
39
- }
40
-
41
- .ui-dialog-buttonpane {
42
- padding-top: 20px;
43
- }
44
-
45
- .ui-button {
46
- font-size: 14px;
47
- line-height: 1em;
48
- border: none;
49
- background: none;
50
- padding: 0;
51
- margin: 0;
52
- cursor: pointer;
53
- }
54
-
55
- .ui-dialog-titlebar-close,
56
- .ui-dialog-titlebar-help {
57
- position: absolute;
58
- right: 0.3em;
59
- top: 50%;
60
- width: 20px;
61
- margin: -10px 0 0;
62
- padding: 1px;
63
- height: 20px;
64
- }
65
-
66
- .ui-button-icon-only {
67
- width: 2em;
68
- box-sizing: border-box;
69
- text-indent: -9999px;
70
- white-space: nowrap;
71
- }
72
-
73
- .ui-button-icon-only .ui-icon {
74
- position: absolute;
75
- top: 50%;
76
- left: 50%;
77
- margin-top: -8px;
78
- margin-left: -8px;
79
- }
80
-
81
- .ui-button-icon-only .ui-icon::before {
82
- text-indent: 5019px;
83
- }
84
-
85
- /* Style for the close button specifically */
86
- .ui-dialog-titlebar-close {
87
- order: 99; /* Push to end of flex container */
88
- }
89
-
90
- .ui-dialog-titlebar-close:hover,
91
- .ui-dialog-titlebar-help:hover {
92
- color: var(--cs-dark-hover);
93
- }
94
-
95
- .ui-icon-closethick::before {
96
- width: 0.7em;
97
- height: 1em;
98
- padding-top: 5px;
99
- content: "\f00d";
100
- }
101
-
102
- .ui-icon-help::before {
103
- width: 0.7em;
104
- height: 1em;
105
- padding-top: 5px;
106
- content: "\f128";
107
- }
108
-
109
- .ui-dialog-content {
110
- position: relative;
111
- margin-top: 24px;
112
- overflow: auto;
113
- }
114
-
115
- .ui-dialog-buttonset {
116
- position: relative;
117
- text-align: right;
118
- }
119
-
120
- .ui-dialog-buttonset .fw-button {
121
- margin-left: 6px;
122
- }
123
-
124
- /* Make focus visible on all focusable elements */
125
- .ui-dialog *:focus {
126
- outline: 2px solid var(--cs-dark-background);
127
- outline-offset: 2px;
128
- }
129
-
130
- /* Style the title bar buttons specifically */
131
- .ui-dialog-titlebar .ui-button-icon-only {
132
- position: absolute;
133
- top: 50%;
134
- transform: translateY(-50%);
135
- padding: 8px;
136
- background: transparent;
137
- border: none;
138
- }
139
-
140
- .ui-dialog-titlebar .ui-button-icon-only:focus {
141
- outline: 2px solid var(--cs-dark-text);
142
- outline-offset: 2px;
143
- border-radius: 4px;
144
- }
@@ -1,7 +0,0 @@
1
- export declare const baseBodyTemplate: ({ user, contents, hasOverview, app }: {
2
- user: any;
3
- contents: any;
4
- hasOverview: any;
5
- app: any;
6
- }) => string;
7
- //# sourceMappingURL=templates.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,GAAI;;;;;CAAkC,WAsC5D,CAAA"}
package/dist/templates.js DELETED
@@ -1,43 +0,0 @@
1
- // @ts-nocheck
2
- import { avatarTemplate } from "./user.js";
3
- import { filterPrimaryEmail } from "./user_util.js";
4
- export const baseBodyTemplate = ({ user, contents, hasOverview, app }) => `
5
- <div id="wait">
6
- <i class="fa fa-spinner fa-pulse"></i>
7
- </div>
8
- <header class="fw-header" role="banner">
9
- <div class="fw-container">
10
- <a href="${app && app.routes[""].app === "document" ? "/" : "/documents/"}">
11
- <h1 class="fw-logo">
12
- <span class="fw-logo-text"></span>
13
- <img src="${staticUrl("svg/icon.svg")}" alt="Logo" />
14
- </h1>
15
- </a>
16
- <nav id="header-nav" role="navigation" aria-label="${gettext("Site navigation")}"></nav>
17
- <div id="user-preferences" class="fw-user-preferences fw-header-text">
18
- <div id="preferences-btn" class="fw-button">
19
- ${avatarTemplate({ user })}
20
- </div>
21
- <div id="user-preferences-pulldown" class="fw-pulldown fw-right">
22
- <div data-value="profile">
23
- <span class='fw-avatar-card'>
24
- <span class='fw-avatar-card-avatar'>${avatarTemplate({ user })}</span>
25
- <span class='fw-avatar-card-name'>
26
- ${user.username}
27
- <span class='fw-avatar-card-email'>${filterPrimaryEmail(user.emails)}</span>
28
- </span>
29
- </span>
30
- </div>
31
- <div data-value="contacts">${gettext("Contacts")}</div>
32
- <div data-value="logout">${gettext("Log out")}</div>
33
- </div>
34
- </div><!-- end user preference -->
35
- </div><!-- end container -->
36
- </header>
37
- <div class="fw-contents-outer">
38
- ${hasOverview ? '<div class="fw-overview-menu-wrapper"><ul id="fw-overview-menu"></ul></div>' : ""}
39
- <div class="fw-contents">
40
- ${contents}
41
- </div>
42
- </div>`;
43
- //# sourceMappingURL=templates.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAC,cAAc,EAAC,MAAM,WAAW,CAAA;AACxC,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAA;AAEjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAC,EAAE,EAAE,CAAC;;;;;;mBAMrD,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa;;;4BAGrD,SAAS,CAAC,cAAc,CAAC;;;6DAGQ,OAAO,CAAC,iBAAiB,CAAC;;;kBAGrE,cAAc,CAAC,EAAC,IAAI,EAAC,CAAC;;;;;8DAKsB,cAAc,CAAC,EAAC,IAAI,EAAC,CAAC;;8BAEtD,IAAI,CAAC,QAAQ;iEACsB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;;;;6CAInD,OAAO,CAAC,UAAU,CAAC;2CACrB,OAAO,CAAC,SAAS,CAAC;;;;;;MAMvD,WAAW,CAAC,CAAC,CAAC,6EAA6E,CAAC,CAAC,CAAC,EAAE;;UAE5F,QAAQ;;OAEX,CAAA"}
@@ -1,7 +0,0 @@
1
- /** Creates a dropdown box.
2
- * @param btn The button to open and close the dropdown box.
3
- * @param box The node containing the contents of the dropdown box.
4
- * @param preopen An optional function to be called before opening the dropdown box. Used to position dropdown box.
5
- */
6
- export declare const filterPrimaryEmail: (emails: any) => any;
7
- //# sourceMappingURL=user_util.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"user_util.d.ts","sourceRoot":"","sources":["../src/user_util.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAG,WAAM,QAUvC,CAAA"}
package/dist/user_util.js DELETED
@@ -1,19 +0,0 @@
1
- // @ts-nocheck
2
- /** Creates a dropdown box.
3
- * @param btn The button to open and close the dropdown box.
4
- * @param box The node containing the contents of the dropdown box.
5
- * @param preopen An optional function to be called before opening the dropdown box. Used to position dropdown box.
6
- */
7
- export const filterPrimaryEmail = emails => {
8
- const primaryEmails = emails.filter(email => email.primary);
9
- if (!primaryEmails.length) {
10
- if (emails.length) {
11
- return emails[0].address;
12
- }
13
- else {
14
- return "";
15
- }
16
- }
17
- return primaryEmails[0].address;
18
- };
19
- //# sourceMappingURL=user_util.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"user_util.js","sourceRoot":"","sources":["../src/user_util.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE;IACvC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC3D,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;QAC5B,CAAC;aAAM,CAAC;YACJ,OAAO,EAAE,CAAA;QACb,CAAC;IACL,CAAC;IACD,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACnC,CAAC,CAAA"}