icon marking resources missing permissions #190
Massimo Melina committed
Apr 2, 2023 at 22:49 UTC
fcb171cef08f8d86487678156ec6228035ad88bb
5 files changed
+19
-6
frontend/src/BrowseFiles.ts
+5
-1
@@ -23,10 +23,12 @@ import _ from 'lodash'
23
import { t, useI18N } from './i18n'
24
import { deleteFiles } from './menu'
25
26
-export interface DirEntry { n:string, s?:number, m?:string, c?:string,
26
+export interface DirEntry { n:string, s?:number, m?:string, c?:string, p?:string,
27
name: string, uri: string, ext:string, isFolder:boolean, t?:Date } // we memoize these value for speed
28
export type DirList = DirEntry[]
29
30
+const MISSING_PERM = "Missing permission"
31
+
32
export function BrowseFiles() {
33
useFetchList()
34
const { error } = useSnapState()
@@ -237,6 +239,7 @@ const Entry = memo((entry: DirEntry & { midnight: Date, separator?: string }) =>
239
h('dl', { className: 'file-dialog-properties' },
240
h('dt', {}, t`Name:`), h('dd', {}, name),
241
),
242
+ entry.p && h(Fragment, {}, hIcon('password', { style: { marginRight: '.5em' } }), t(MISSING_PERM)),
243
h('div', { className: 'file-menu' },
244
menu.map((e: any, i) => !e?.label ? null :
245
h('a', {
@@ -264,6 +267,7 @@ const EntryProps = memo((entry: DirEntry & { midnight: Date }) => {
267
const dd = '2-digit'
268
return h('div', { className: 'entry-props' },
269
h(CustomCode, { name: 'additionalEntryProps', props: { entry } }),
270
+ entry.p && hIcon('password', { className: 'miss-perm', title: t(MISSING_PERM) }),
271
h(EntrySize, { s }),
272
time && h('span', {
273
className: 'entry-ts',
frontend/src/index.scss
+3
@@ -383,8 +383,11 @@ button label {
383
}
384
}
385
386
+.miss-perm { margin: .3em }
387
+
388
.file-dialog-properties {
389
word-break: break-word;
390
+ line-height: 1.5em;
391
& dd { margin-left: 1.5em; }
392
}
393
.file-menu {
langs/hfs-lang-en.json
+2
-1
@@ -107,6 +107,7 @@
107
"File menu": "File menu",
108
"Name:": "Name:",
109
"file_open": "Open",
110
- "Download": "Download"
110
+ "Download": "Download",
111
+ "Missing permission": "Missing permission"
112
}
113
}
langs/hfs-lang-it.json
+2
-1
@@ -101,6 +101,7 @@
101
"File menu": "Menu file",
102
"Name:": "Nome:",
103
"file_open": "Apri",
104
- "Download": "Download"
104
+ "Download": "Download",
105
+ "Missing permission": "Permesso mancante"
106
}
107
}
src/api.file_list.ts
+7
-3
@@ -15,6 +15,7 @@ import { mapPlugins } from './plugins'
15
import { asyncGeneratorToArray, dirTraversal, pattern2filter } from './misc'
16
import _ from 'lodash'
17
import { HTTP_BAD_REQUEST, HTTP_FOOL, HTTP_METHOD_NOT_ALLOWED, HTTP_NOT_FOUND } from './const'
18
+import Koa from 'koa'
19
20
export const file_list: ApiHandler = async ({ path, offset, limit, search, omit, sse }, ctx) => {
21
let node = await urlToNode(path || '/', ctx)
@@ -63,7 +64,7 @@ export const file_list: ApiHandler = async ({ path, offset, limit, search, omit,
64
if (ctx.aborted) break
65
if (!filter(getNodeName(sub)))
66
continue
66
- const entry = await nodeToDirEntry(sub)
67
+ const entry = await nodeToDirEntry(ctx, sub)
68
if (!entry)
69
continue
70
const cbParams = { entry, ctx, listPath:path, node:sub }
@@ -92,9 +93,9 @@ export const file_list: ApiHandler = async ({ path, offset, limit, search, omit,
93
}
94
}
95
95
-export interface DirEntry { n:string, s?:number, m?:Date, c?:Date }
96
+export interface DirEntry { n:string, s?:number, m?:Date, c?:Date, p?: string }
97
97
-async function nodeToDirEntry(node: VfsNode): Promise<DirEntry | null> {
98
+async function nodeToDirEntry(ctx: Koa.Context, node: VfsNode): Promise<DirEntry | null> {
99
let { source, default:def } = node
100
const name = getNodeName(node)
101
if (!source)
@@ -110,6 +111,9 @@ async function nodeToDirEntry(node: VfsNode): Promise<DirEntry | null> {
111
c: ctime,
112
m: Math.abs(+mtime-+ctime) < 1000 ? undefined : mtime,
113
s: folder ? undefined : st.size,
114
+ p: ((hasPermission(node, 'can_read', ctx) ? '' : 'R')
115
+ + (hasPermission(node, 'can_list', ctx) ? '' : 'L'))
116
+ || undefined
117
}
118
}
119
catch {