change readonly boolean to role enum

This commit is contained in:
mgabor
2024-04-17 09:31:56 +02:00
parent 9126bf2520
commit 87bc244b68
30 changed files with 297 additions and 141 deletions

View File

@@ -4,8 +4,8 @@
removeUserFromAlbum,
type AlbumResponseDto,
type UserResponseDto,
updateAlbumUser,
} from '@immich/sdk';
updateAlbumUser, AlbumUserRole,
} from '@immich/sdk'
import { mdiDotsVertical } from '@mdi/js';
import { createEventDispatcher, onMount } from 'svelte';
import { getContextMenuPosition } from '../../utils/context-menu';
@@ -71,10 +71,10 @@
}
};
const handleSetReadonly = async (user: UserResponseDto, readonly: boolean) => {
const handleSetReadonly = async (user: UserResponseDto, role: AlbumUserRole) => {
try {
await updateAlbumUser({ id: album.id, userId: user.id, updateAlbumUserDto: { readonly } });
const message = readonly ? `Set ${user.name} as viewer` : `Set ${user.name} as editor`;
await updateAlbumUser({ id: album.id, userId: user.id, updateAlbumUserDto: { role } });
const message = `Set ${user.name} as ${role}`;
dispatch('refreshAlbum');
notificationController.show({ type: NotificationType.Info, message });
} catch (error) {
@@ -99,14 +99,14 @@
</div>
</div>
{#each album.sharedUsersV2.toSorted((a, b) => {
if (a.readonly && !b.readonly) {
if (a.role === AlbumUserRole.Viewer && b.role === AlbumUserRole.Editor) {
return 1;
}
if (!a.readonly && b.readonly) {
if (a.role === AlbumUserRole.Editor && b.role === AlbumUserRole.Viewer) {
return -1;
}
return a.user.name.localeCompare(b.user.name);
}) as { user, readonly }}
}) as { user, role }}
<div
class="flex w-full place-items-center justify-between gap-4 p-5 transition-colors hover:bg-gray-50 dark:hover:bg-gray-700"
>
@@ -117,7 +117,7 @@
<div id="icon-{user.id}" class="flex place-items-center gap-2">
<div>
{#if readonly}
{#if role === AlbumUserRole.Viewer}
Viewer
{:else}
Editor
@@ -136,10 +136,10 @@
{#if selectedMenuUser === user}
<ContextMenu {...position} on:outclick={() => (selectedMenuUser = null)}>
{#if readonly}
<MenuOption on:click={() => handleSetReadonly(user, false)} text="Allow edits" />
{#if role === AlbumUserRole.Viewer}
<MenuOption on:click={() => handleSetReadonly(user, AlbumUserRole.Editor)} text="Allow edits" />
{:else}
<MenuOption on:click={() => handleSetReadonly(user, true)} text="Disallow edits" />
<MenuOption on:click={() => handleSetReadonly(user, AlbumUserRole.Viewer)} text="Disallow edits" />
{/if}
<MenuOption on:click={handleMenuRemove} text="Remove" />
</ContextMenu>

View File

@@ -1,84 +1,83 @@
<script lang="ts">
import { afterNavigate, goto } from '$app/navigation';
import AlbumOptions from '$lib/components/album-page/album-options.svelte';
import ShareInfoModal from '$lib/components/album-page/share-info-modal.svelte';
import UserSelectionModal from '$lib/components/album-page/user-selection-modal.svelte';
import ActivityStatus from '$lib/components/asset-viewer/activity-status.svelte';
import ActivityViewer from '$lib/components/asset-viewer/activity-viewer.svelte';
import Button from '$lib/components/elements/buttons/button.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import Icon from '$lib/components/elements/icon.svelte';
import AddToAlbum from '$lib/components/photos-page/actions/add-to-album.svelte';
import ArchiveAction from '$lib/components/photos-page/actions/archive-action.svelte';
import ChangeDate from '$lib/components/photos-page/actions/change-date-action.svelte';
import ChangeLocation from '$lib/components/photos-page/actions/change-location-action.svelte';
import CreateSharedLink from '$lib/components/photos-page/actions/create-shared-link.svelte';
import DeleteAssets from '$lib/components/photos-page/actions/delete-assets.svelte';
import DownloadAction from '$lib/components/photos-page/actions/download-action.svelte';
import FavoriteAction from '$lib/components/photos-page/actions/favorite-action.svelte';
import RemoveFromAlbum from '$lib/components/photos-page/actions/remove-from-album.svelte';
import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte';
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte';
import {afterNavigate, goto} from '$app/navigation'
import AlbumDescription from '$lib/components/album-page/album-description.svelte'
import AlbumOptions from '$lib/components/album-page/album-options.svelte'
import AlbumSummary from '$lib/components/album-page/album-summary.svelte'
import AlbumTitle from '$lib/components/album-page/album-title.svelte'
import ShareInfoModal from '$lib/components/album-page/share-info-modal.svelte'
import UserSelectionModal from '$lib/components/album-page/user-selection-modal.svelte'
import ActivityStatus from '$lib/components/asset-viewer/activity-status.svelte'
import ActivityViewer from '$lib/components/asset-viewer/activity-viewer.svelte'
import Button from '$lib/components/elements/buttons/button.svelte'
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte'
import Icon from '$lib/components/elements/icon.svelte'
import AddToAlbum from '$lib/components/photos-page/actions/add-to-album.svelte'
import ArchiveAction from '$lib/components/photos-page/actions/archive-action.svelte'
import ChangeDate from '$lib/components/photos-page/actions/change-date-action.svelte'
import ChangeLocation from '$lib/components/photos-page/actions/change-location-action.svelte'
import CreateSharedLink from '$lib/components/photos-page/actions/create-shared-link.svelte'
import DeleteAssets from '$lib/components/photos-page/actions/delete-assets.svelte'
import DownloadAction from '$lib/components/photos-page/actions/download-action.svelte'
import FavoriteAction from '$lib/components/photos-page/actions/favorite-action.svelte'
import RemoveFromAlbum from '$lib/components/photos-page/actions/remove-from-album.svelte'
import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte'
import AssetGrid from '$lib/components/photos-page/asset-grid.svelte'
import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte'
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte'
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte'
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte'
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte'
import CreateSharedLinkModal
from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte'
import {notificationController, NotificationType,} from '$lib/components/shared-components/notification/notification'
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte'
import {AppRoute} from '$lib/constants'
import {numberOfComments, setNumberOfComments, updateNumberOfComments} from '$lib/stores/activity.store'
import {createAssetInteractionStore} from '$lib/stores/asset-interaction.store'
import {assetViewingStore} from '$lib/stores/asset-viewing.store'
import {AssetStore} from '$lib/stores/assets.store'
import {locale} from '$lib/stores/preferences.store'
import {SlideshowNavigation, SlideshowState, slideshowStore} from '$lib/stores/slideshow.store'
import {user} from '$lib/stores/user.store'
import {handlePromiseError} from '$lib/utils'
import {downloadAlbum} from '$lib/utils/asset-utils'
import {clickOutside} from '$lib/utils/click-outside'
import {getContextMenuPosition} from '$lib/utils/context-menu'
import {openFileUploadDialog} from '$lib/utils/file-uploader'
import {handleError} from '$lib/utils/handle-error'
import {
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import { AppRoute } from '$lib/constants';
import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store';
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { AssetStore } from '$lib/stores/assets.store';
import { locale } from '$lib/stores/preferences.store';
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
import { user } from '$lib/stores/user.store';
import { downloadAlbum } from '$lib/utils/asset-utils';
import { clickOutside } from '$lib/utils/click-outside';
import { getContextMenuPosition } from '$lib/utils/context-menu';
import { openFileUploadDialog } from '$lib/utils/file-uploader';
import { handleError } from '$lib/utils/handle-error';
import {
ReactionLevel,
ReactionType,
type ActivityResponseDto,
addAssetsToAlbum,
addUsersToAlbum,
AlbumUserRole,
AssetOrder,
createActivity,
deleteActivity,
deleteAlbum,
getActivities,
getActivityStatistics,
getAlbumInfo,
ReactionLevel,
ReactionType,
updateAlbumInfo,
type ActivityResponseDto,
type UserResponseDto,
AssetOrder,
} from '@immich/sdk';
} from '@immich/sdk'
import {
mdiArrowLeft,
mdiCogOutline,
mdiDeleteOutline,
mdiDotsVertical,
mdiFolderDownloadOutline,
mdiLink,
mdiPlus,
mdiShareVariantOutline,
mdiPresentationPlay,
mdiCogOutline,
mdiImageOutline,
mdiImagePlusOutline,
} from '@mdi/js';
import { fly } from 'svelte/transition';
import type { PageData } from './$types';
import AlbumTitle from '$lib/components/album-page/album-title.svelte';
import AlbumDescription from '$lib/components/album-page/album-description.svelte';
import { handlePromiseError } from '$lib/utils';
import AlbumSummary from '$lib/components/album-page/album-summary.svelte';
mdiLink,
mdiPlus,
mdiPresentationPlay,
mdiShareVariantOutline,
} from '@mdi/js'
import {fly} from 'svelte/transition'
import type {PageData} from './$types'
export let data: PageData;
@@ -136,8 +135,8 @@
$: showActivityStatus =
album.sharedUsers.length > 0 && !$showAssetViewer && (album.isActivityEnabled || $numberOfComments > 0);
$: userHasWriteAccess = !album.sharedUsersV2.find(({ user: { id } }) => id === $user.id)?.readonly;
$: albumHasReadonlyUsers = album.sharedUsersV2.some(({ readonly }) => readonly);
$: isEditor = album.sharedUsersV2.find(({ user: { id } }) => id === $user.id)?.role === AlbumUserRole.Editor;
$: albumHasViewers = album.sharedUsersV2.some(({ role }) => role === AlbumUserRole.Viewer);
afterNavigate(({ from }) => {
assetViewingStore.showAssetViewer(false);
@@ -436,7 +435,7 @@
{#if viewMode === ViewMode.VIEW || viewMode === ViewMode.ALBUM_OPTIONS}
<ControlAppBar showBackButton backIcon={mdiArrowLeft} on:close={() => goto(backUrl)}>
<svelte:fragment slot="trailing">
{#if userHasWriteAccess}
{#if isEditor}
<CircleIconButton
title="Add photos"
on:click={() => (viewMode = ViewMode.SELECT_ASSETS)}
@@ -584,14 +583,14 @@
</button>
<!-- users with write access (collaborators) -->
{#each album.sharedUsersV2.filter(({ readonly }) => !readonly) as { user } (user.id)}
{#each album.sharedUsersV2.filter(({ role }) => role === AlbumUserRole.Editor) as { user } (user.id)}
<button on:click={() => (viewMode = ViewMode.VIEW_USERS)}>
<UserAvatar {user} size="md" />
</button>
{/each}
<!-- display ellipsis if there are readonly users too -->
{#if albumHasReadonlyUsers}
{#if albumHasViewers}
<CircleIconButton
title="View all users"
backgroundColor="#d3d3d3"