enh: read only notes
This commit is contained in:
@@ -157,6 +157,16 @@
|
||||
if (res) {
|
||||
note = res;
|
||||
files = res.data.files || [];
|
||||
|
||||
if (note?.write_access) {
|
||||
$socket?.emit('join-note', {
|
||||
note_id: id,
|
||||
auth: {
|
||||
token: localStorage.token
|
||||
}
|
||||
});
|
||||
$socket?.on('note-events', noteEventHandler);
|
||||
}
|
||||
} else {
|
||||
goto('/');
|
||||
return;
|
||||
@@ -781,13 +791,6 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||
|
||||
onMount(async () => {
|
||||
await tick();
|
||||
$socket?.emit('join-note', {
|
||||
note_id: id,
|
||||
auth: {
|
||||
token: localStorage.token
|
||||
}
|
||||
});
|
||||
$socket?.on('note-events', noteEventHandler);
|
||||
|
||||
if ($settings?.models) {
|
||||
selectedModelId = $settings?.models[0];
|
||||
@@ -956,70 +959,72 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center gap-0.5 translate-x-1">
|
||||
{#if editor}
|
||||
<div>
|
||||
<div class="flex items-center gap-0.5 self-center min-w-fit" dir="ltr">
|
||||
<button
|
||||
class="self-center p-1 hover:enabled:bg-black/5 dark:hover:enabled:bg-white/5 dark:hover:enabled:text-white hover:enabled:text-black rounded-md transition disabled:cursor-not-allowed disabled:text-gray-500 disabled:hover:text-gray-500"
|
||||
on:click={() => {
|
||||
editor.chain().focus().undo().run();
|
||||
// versionNavigateHandler('prev');
|
||||
}}
|
||||
disabled={!editor.can().undo()}
|
||||
>
|
||||
<ArrowUturnLeft className="size-4" />
|
||||
</button>
|
||||
{#if note?.write_access}
|
||||
{#if editor}
|
||||
<div>
|
||||
<div class="flex items-center gap-0.5 self-center min-w-fit" dir="ltr">
|
||||
<button
|
||||
class="self-center p-1 hover:enabled:bg-black/5 dark:hover:enabled:bg-white/5 dark:hover:enabled:text-white hover:enabled:text-black rounded-md transition disabled:cursor-not-allowed disabled:text-gray-500 disabled:hover:text-gray-500"
|
||||
on:click={() => {
|
||||
editor.chain().focus().undo().run();
|
||||
// versionNavigateHandler('prev');
|
||||
}}
|
||||
disabled={!editor.can().undo()}
|
||||
>
|
||||
<ArrowUturnLeft className="size-4" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="self-center p-1 hover:enabled:bg-black/5 dark:hover:enabled:bg-white/5 dark:hover:enabled:text-white hover:enabled:text-black rounded-md transition disabled:cursor-not-allowed disabled:text-gray-500 disabled:hover:text-gray-500"
|
||||
on:click={() => {
|
||||
editor.chain().focus().redo().run();
|
||||
// versionNavigateHandler('next');
|
||||
}}
|
||||
disabled={!editor.can().redo()}
|
||||
>
|
||||
<ArrowUturnRight className="size-4" />
|
||||
</button>
|
||||
<button
|
||||
class="self-center p-1 hover:enabled:bg-black/5 dark:hover:enabled:bg-white/5 dark:hover:enabled:text-white hover:enabled:text-black rounded-md transition disabled:cursor-not-allowed disabled:text-gray-500 disabled:hover:text-gray-500"
|
||||
on:click={() => {
|
||||
editor.chain().focus().redo().run();
|
||||
// versionNavigateHandler('next');
|
||||
}}
|
||||
disabled={!editor.can().redo()}
|
||||
>
|
||||
<ArrowUturnRight className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<Tooltip placement="top" content={$i18n.t('Chat')} className="cursor-pointer">
|
||||
<button
|
||||
class="p-1.5 bg-transparent hover:bg-white/5 transition rounded-lg"
|
||||
on:click={() => {
|
||||
if (showPanel && selectedPanel === 'chat') {
|
||||
showPanel = false;
|
||||
} else {
|
||||
if (!showPanel) {
|
||||
showPanel = true;
|
||||
}
|
||||
selectedPanel = 'chat';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ChatBubbleOval />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip placement="top" content={$i18n.t('Controls')} className="cursor-pointer">
|
||||
<button
|
||||
class="p-1.5 bg-transparent hover:bg-white/5 transition rounded-lg"
|
||||
on:click={() => {
|
||||
if (showPanel && selectedPanel === 'settings') {
|
||||
showPanel = false;
|
||||
} else {
|
||||
if (!showPanel) {
|
||||
showPanel = true;
|
||||
}
|
||||
selectedPanel = 'settings';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AdjustmentsHorizontalOutline />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
<Tooltip placement="top" content={$i18n.t('Chat')} className="cursor-pointer">
|
||||
<button
|
||||
class="p-1.5 bg-transparent hover:bg-white/5 transition rounded-lg"
|
||||
on:click={() => {
|
||||
if (showPanel && selectedPanel === 'chat') {
|
||||
showPanel = false;
|
||||
} else {
|
||||
if (!showPanel) {
|
||||
showPanel = true;
|
||||
}
|
||||
selectedPanel = 'chat';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ChatBubbleOval />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip placement="top" content={$i18n.t('Controls')} className="cursor-pointer">
|
||||
<button
|
||||
class="p-1.5 bg-transparent hover:bg-white/5 transition rounded-lg"
|
||||
on:click={() => {
|
||||
if (showPanel && selectedPanel === 'settings') {
|
||||
showPanel = false;
|
||||
} else {
|
||||
if (!showPanel) {
|
||||
showPanel = true;
|
||||
}
|
||||
selectedPanel = 'settings';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AdjustmentsHorizontalOutline />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<NoteMenu
|
||||
onDownload={(type) => {
|
||||
downloadHandler(type);
|
||||
@@ -1071,11 +1076,9 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="flex gap-1 items-center text-xs font-medium text-gray-500 dark:text-gray-500 w-fit"
|
||||
class="flex gap-0.5 items-center text-xs font-medium text-gray-500 dark:text-gray-500 w-fit"
|
||||
>
|
||||
<button class=" flex items-center gap-1 w-fit py-1 px-1.5 rounded-lg min-w-fit">
|
||||
<Calendar className="size-3.5" strokeWidth="2" />
|
||||
|
||||
<!-- check for same date, yesterday, last week, and other -->
|
||||
|
||||
{#if dayjs(note.created_at / 1000000).isSame(dayjs(), 'day')}
|
||||
@@ -1099,17 +1102,21 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button
|
||||
class=" flex items-center gap-1 w-fit py-1 px-1.5 rounded-lg min-w-fit"
|
||||
on:click={() => {
|
||||
showAccessControlModal = true;
|
||||
}}
|
||||
disabled={note?.user_id !== $user?.id && $user?.role !== 'admin'}
|
||||
>
|
||||
<Users className="size-3.5" strokeWidth="2" />
|
||||
|
||||
<span> {note?.access_control ? $i18n.t('Private') : $i18n.t('Everyone')} </span>
|
||||
</button>
|
||||
{#if note?.write_access}
|
||||
<button
|
||||
class=" flex items-center gap-1 w-fit py-1 px-1.5 rounded-lg min-w-fit"
|
||||
on:click={() => {
|
||||
showAccessControlModal = true;
|
||||
}}
|
||||
disabled={note?.user_id !== $user?.id && $user?.role !== 'admin'}
|
||||
>
|
||||
<span> {note?.access_control ? $i18n.t('Private') : $i18n.t('Everyone')} </span>
|
||||
</button>
|
||||
{:else}
|
||||
<div>
|
||||
{$i18n.t('Read-Only Access')}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if editor}
|
||||
<div class="flex items-center gap-1 px-1 min-w-fit">
|
||||
@@ -1158,7 +1165,7 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||
image={true}
|
||||
{files}
|
||||
placeholder={$i18n.t('Write something...')}
|
||||
editable={versionIdx === null && !editing}
|
||||
editable={versionIdx === null && !editing && note?.write_access}
|
||||
onSelectionUpdate={({ editor }) => {
|
||||
const { from, to } = editor.state.selection;
|
||||
const selectedText = editor.state.doc.textBetween(from, to, ' ');
|
||||
|
||||
@@ -163,17 +163,33 @@
|
||||
await getItemsPage();
|
||||
};
|
||||
|
||||
$: if (loaded && query !== undefined && sortKey !== undefined && viewOption !== undefined) {
|
||||
$: if (
|
||||
loaded &&
|
||||
query !== undefined &&
|
||||
sortKey !== undefined &&
|
||||
permission !== undefined &&
|
||||
viewOption !== undefined
|
||||
) {
|
||||
init();
|
||||
}
|
||||
|
||||
const getItemsPage = async () => {
|
||||
itemsLoading = true;
|
||||
const res = await searchNotes(localStorage.token, query, viewOption, sortKey, page).catch(
|
||||
() => {
|
||||
return [];
|
||||
}
|
||||
);
|
||||
|
||||
if (viewOption === 'created') {
|
||||
permission = null;
|
||||
}
|
||||
|
||||
const res = await searchNotes(
|
||||
localStorage.token,
|
||||
query,
|
||||
viewOption,
|
||||
permission,
|
||||
sortKey,
|
||||
page
|
||||
).catch(() => {
|
||||
return [];
|
||||
});
|
||||
|
||||
if (res) {
|
||||
console.log(res);
|
||||
@@ -367,7 +383,7 @@
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="flex gap-1.5 w-fit text-center text-sm rounded-full bg-transparent px-0.5 whitespace-nowrap"
|
||||
class="flex gap-3 w-fit text-center text-sm rounded-full bg-transparent px-0.5 whitespace-nowrap"
|
||||
>
|
||||
<DropdownOptions
|
||||
align="start"
|
||||
@@ -386,6 +402,17 @@
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{#if [null, 'shared'].includes(viewOption)}
|
||||
<DropdownOptions
|
||||
align="start"
|
||||
bind:value={permission}
|
||||
items={[
|
||||
{ value: null, label: $i18n.t('Write') },
|
||||
{ value: 'read_only', label: $i18n.t('Read Only') }
|
||||
]}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -411,17 +438,21 @@
|
||||
{#if (items ?? []).length > 0}
|
||||
{@const notes = groupNotes(items)}
|
||||
|
||||
<div class="@container h-full py-2 px-2.5">
|
||||
<div class="@container h-full py-2.5 px-2.5">
|
||||
<div class="">
|
||||
{#each Object.keys(notes) as timeRange}
|
||||
{#each Object.keys(notes) as timeRange, idx}
|
||||
<div
|
||||
class="mb-3 w-full text-xs text-gray-500 dark:text-gray-500 font-medium px-2.5 pb-2.5"
|
||||
class="w-full text-xs text-gray-500 dark:text-gray-500 font-medium px-2.5 pb-2.5"
|
||||
>
|
||||
{$i18n.t(timeRange)}
|
||||
</div>
|
||||
|
||||
{#if displayOption === null}
|
||||
<div class="gap-1.5 flex flex-col">
|
||||
<div
|
||||
class="{Object.keys(notes).length - 1 !== idx
|
||||
? 'mb-3'
|
||||
: ''} gap-1.5 flex flex-col"
|
||||
>
|
||||
{#each notes[timeRange] as note, idx (note.id)}
|
||||
<div
|
||||
class=" flex cursor-pointer w-full px-3.5 py-1.5 border border-gray-50 dark:border-gray-850/30 bg-transparent dark:hover:bg-gray-850 hover:bg-white rounded-2xl transition"
|
||||
@@ -494,7 +525,9 @@
|
||||
</div>
|
||||
{:else if displayOption === 'grid'}
|
||||
<div
|
||||
class="mb-5 gap-2.5 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5"
|
||||
class="{Object.keys(notes).length - 1 !== idx
|
||||
? 'mb-5'
|
||||
: ''} gap-2.5 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5"
|
||||
>
|
||||
{#each notes[timeRange] as note, idx (note.id)}
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user