mirror of
https://github.com/immich-app/immich.git
synced 2026-02-14 12:58:17 +03:00
change readonly boolean to role enum
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user