chore: vault member permissions (#2509)

This commit is contained in:
Aman Harwara
2023-09-18 19:53:34 +05:30
committed by GitHub
parent 2af610c7bf
commit 48e7820100
32 changed files with 331 additions and 94 deletions

View File

@@ -10,6 +10,7 @@ import {
SNNote,
NoteType,
PayloadEmitSource,
VaultServiceInterface,
} from '@standardnotes/snjs'
import NoteView from './NoteView'
import { NoteViewController } from './Controller/NoteViewController'
@@ -19,6 +20,7 @@ describe('NoteView', () => {
let application: WebApplication
let notesController: NotesController
let vaults: VaultServiceInterface
const createNoteView = () =>
new NoteView({
@@ -36,9 +38,13 @@ describe('NoteView', () => {
notesController.getSpellcheckStateForNote = jest.fn()
notesController.getEditorWidthForNote = jest.fn()
vaults = {} as jest.Mocked<VaultServiceInterface>
vaults.getItemVault = jest.fn().mockReturnValue(undefined)
application = {
notesController,
noteViewController,
vaults,
} as unknown as jest.Mocked<WebApplication>
application.hasProtectionSources = jest.fn().mockReturnValue(true)

View File

@@ -68,6 +68,7 @@ type State = {
isDesktop?: boolean
editorLineWidth: EditorLineWidth
noteLocked: boolean
readonly: boolean
noteStatus?: NoteStatus
saveError?: boolean
showProtectedWarning: boolean
@@ -116,6 +117,8 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
this.debounceReloadEditorComponent = debounce(this.debounceReloadEditorComponent.bind(this), 25)
const itemVault = this.application.vaults.getItemVault(this.controller.item)
this.state = {
availableStackComponents: [],
editorStateDidLoad: false,
@@ -124,6 +127,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
isDesktop: isDesktopApplication(),
noteStatus: undefined,
noteLocked: this.controller.item.locked,
readonly: itemVault ? this.application.vaultUsers.isCurrentUserReadonlyVaultMember(itemVault) : false,
showProtectedWarning: false,
spellcheck: true,
stackComponentViewers: [],
@@ -855,6 +859,13 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
/>
)}
{this.state.readonly && (
<div className="bg-warning-faded flex items-center px-3.5 py-2 text-sm text-accessory-tint-3">
<Icon type="pencil-off" className="mr-3" />
You don't have permission to edit this note
</div>
)}
{this.state.noteLocked && (
<EditingDisabledBanner
onClick={() => this.application.notesController.setLockSelectedNotes(!this.state.noteLocked)}
@@ -878,7 +889,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
<div className="title flex-grow overflow-auto">
<input
className="input text-lg"
disabled={this.state.noteLocked}
disabled={this.state.noteLocked || this.state.readonly}
id={ElementIds.NoteTitleEditor}
onChange={this.onTitleChange}
onFocus={(event) => {
@@ -911,18 +922,22 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
)}
{renderHeaderOptions && (
<div className="note-view-options-buttons flex items-center gap-3">
<LinkedItemsButton
linkingController={this.application.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<ChangeEditorButton
noteViewController={this.controller}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<PinNoteButton
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
{!this.state.readonly && (
<>
<LinkedItemsButton
linkingController={this.application.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<ChangeEditorButton
noteViewController={this.controller}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<PinNoteButton
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</>
)}
<NotesOptionsPanel
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
@@ -934,7 +949,11 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
<CollaborationInfoHUD item={this.note} />
</div>
<div className="hidden md:block">
<LinkedItemBubblesContainer item={this.note} linkingController={this.application.linkingController} />
<LinkedItemBubblesContainer
item={this.note}
linkingController={this.application.linkingController}
readonly={this.state.readonly}
/>
</div>
</div>
)}
@@ -961,6 +980,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
componentViewer={this.state.editorComponentViewer}
onLoad={this.onEditorComponentLoad}
requestReload={this.editorComponentViewerRequestsReload}
readonly={this.state.readonly}
/>
</div>
)}
@@ -971,7 +991,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
spellcheck={this.state.spellcheck}
ref={this.setPlainEditorRef}
controller={this.controller}
locked={this.state.noteLocked}
locked={this.state.noteLocked || this.state.readonly}
onFocus={this.onPlainFocus}
onBlur={this.onPlainBlur}
/>
@@ -986,6 +1006,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
filesController={this.application.filesController}
spellcheck={this.state.spellcheck}
controller={this.controller}
readonly={this.state.readonly}
/>
</div>
)}