mirror of
https://github.com/immich-app/immich.git
synced 2024-12-27 10:58:13 +02:00
fix(web): User removal from option menu on the top in shared album (#12959)
* bug fix * added few more type hint * onMount removed, removed current user to user * user check removed and conflict in view mode resolved between option and share info modal * format fix --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
53358c768c
commit
1baa49edb7
@ -1,7 +1,13 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { updateAlbumInfo, type AlbumResponseDto, type UserResponseDto, AssetOrder } from '@immich/sdk';
|
||||
import { mdiArrowDownThin, mdiArrowUpThin, mdiPlus } from '@mdi/js';
|
||||
import {
|
||||
updateAlbumInfo,
|
||||
removeUserFromAlbum,
|
||||
type AlbumResponseDto,
|
||||
type UserResponseDto,
|
||||
AssetOrder,
|
||||
} from '@immich/sdk';
|
||||
import { mdiArrowDownThin, mdiArrowUpThin, mdiPlus, mdiDotsVertical } from '@mdi/js';
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
@ -10,14 +16,21 @@
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { findKey } from 'lodash-es';
|
||||
import { t } from 'svelte-i18n';
|
||||
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
||||
import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte';
|
||||
import { notificationController, NotificationType } from '../shared-components/notification/notification';
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
export let order: AssetOrder | undefined;
|
||||
export let user: UserResponseDto;
|
||||
export let user: UserResponseDto; // Declare user as a prop
|
||||
export let onChangeOrder: (order: AssetOrder) => void;
|
||||
export let onClose: () => void;
|
||||
export let onToggleEnabledActivity: () => void;
|
||||
export let onShowSelectSharedUser: () => void;
|
||||
export let onRemove: (userId: string) => void;
|
||||
|
||||
let selectedRemoveUser: UserResponseDto | null = null;
|
||||
|
||||
const options: Record<AssetOrder, RenderedOption> = {
|
||||
[AssetOrder.Asc]: { icon: mdiArrowUpThin, title: $t('oldest_first') },
|
||||
@ -26,11 +39,11 @@
|
||||
|
||||
$: selectedOption = order ? options[order] : options[AssetOrder.Desc];
|
||||
|
||||
const handleToggle = async (returnedOption: RenderedOption) => {
|
||||
const handleToggle = async (returnedOption: RenderedOption): Promise<void> => {
|
||||
if (selectedOption === returnedOption) {
|
||||
return;
|
||||
}
|
||||
let order = AssetOrder.Desc;
|
||||
let order: AssetOrder = AssetOrder.Desc;
|
||||
order = findKey(options, (option) => option === returnedOption) as AssetOrder;
|
||||
|
||||
try {
|
||||
@ -45,54 +58,96 @@
|
||||
handleError(error, $t('errors.unable_to_save_album'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleMenuRemove = (user: UserResponseDto): void => {
|
||||
selectedRemoveUser = user;
|
||||
};
|
||||
|
||||
const handleRemoveUser = async (): Promise<void> => {
|
||||
if (!selectedRemoveUser) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await removeUserFromAlbum({ id: album.id, userId: selectedRemoveUser.id });
|
||||
onRemove(selectedRemoveUser.id);
|
||||
notificationController.show({
|
||||
type: NotificationType.Info,
|
||||
message: $t('album_user_removed', { values: { user: selectedRemoveUser.name } }),
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.unable_to_remove_album_users'));
|
||||
} finally {
|
||||
selectedRemoveUser = null;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<FullScreenModal title={$t('options')} {onClose}>
|
||||
<div class="items-center justify-center">
|
||||
<div class="py-2">
|
||||
<h2 class="text-gray text-sm mb-2">{$t('settings').toUpperCase()}</h2>
|
||||
<div class="grid p-2 gap-y-2">
|
||||
{#if order}
|
||||
<SettingDropdown
|
||||
title={$t('display_order')}
|
||||
options={Object.values(options)}
|
||||
selectedOption={options[order]}
|
||||
onToggle={handleToggle}
|
||||
{#if !selectedRemoveUser}
|
||||
<FullScreenModal title={$t('options')} {onClose}>
|
||||
<div class="items-center justify-center">
|
||||
<div class="py-2">
|
||||
<h2 class="text-gray text-sm mb-2">{$t('settings').toUpperCase()}</h2>
|
||||
<div class="grid p-2 gap-y-2">
|
||||
{#if order}
|
||||
<SettingDropdown
|
||||
title={$t('display_order')}
|
||||
options={Object.values(options)}
|
||||
selectedOption={options[order]}
|
||||
onToggle={handleToggle}
|
||||
/>
|
||||
{/if}
|
||||
<SettingSwitch
|
||||
title={$t('comments_and_likes')}
|
||||
subtitle={$t('let_others_respond')}
|
||||
checked={album.isActivityEnabled}
|
||||
onToggle={onToggleEnabledActivity}
|
||||
/>
|
||||
{/if}
|
||||
<SettingSwitch
|
||||
title={$t('comments_and_likes')}
|
||||
subtitle={$t('let_others_respond')}
|
||||
checked={album.isActivityEnabled}
|
||||
onToggle={onToggleEnabledActivity}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<div class="text-gray text-sm mb-3">{$t('people').toUpperCase()}</div>
|
||||
<div class="p-2">
|
||||
<button type="button" class="flex items-center gap-2" on:click={onShowSelectSharedUser}>
|
||||
<div class="rounded-full w-10 h-10 border border-gray-500 flex items-center justify-center">
|
||||
<div><Icon path={mdiPlus} size="25" /></div>
|
||||
</div>
|
||||
<div>{$t('invite_people')}</div>
|
||||
</button>
|
||||
<div class="flex items-center gap-2 py-2 mt-2">
|
||||
<div>
|
||||
<UserAvatar {user} size="md" />
|
||||
</div>
|
||||
<div class="w-full">{user.name}</div>
|
||||
<div>{$t('owner')}</div>
|
||||
</div>
|
||||
{#each album.albumUsers as { user } (user.id)}
|
||||
<div class="flex items-center gap-2 py-2">
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<div class="text-gray text-sm mb-3">{$t('people').toUpperCase()}</div>
|
||||
<div class="p-2">
|
||||
<button type="button" class="flex items-center gap-2" on:click={onShowSelectSharedUser}>
|
||||
<div class="rounded-full w-10 h-10 border border-gray-500 flex items-center justify-center">
|
||||
<div><Icon path={mdiPlus} size="25" /></div>
|
||||
</div>
|
||||
<div>{$t('invite_people')}</div>
|
||||
</button>
|
||||
|
||||
<div class="flex items-center gap-2 py-2 mt-2">
|
||||
<div>
|
||||
<UserAvatar {user} size="md" />
|
||||
</div>
|
||||
<div class="w-full">{user.name}</div>
|
||||
<div>{$t('owner')}</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
{#each album.albumUsers as { user } (user.id)}
|
||||
<div class="flex items-center gap-2 py-2">
|
||||
<div>
|
||||
<UserAvatar {user} size="md" />
|
||||
</div>
|
||||
<div class="w-full">{user.name}</div>
|
||||
{#if user.id !== album.ownerId}
|
||||
<!-- Allow deletion for non-owners -->
|
||||
<ButtonContextMenu icon={mdiDotsVertical} size="20" title={$t('options')}>
|
||||
<MenuOption onClick={() => handleMenuRemove(user)} text={$t('remove')} />
|
||||
</ButtonContextMenu>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FullScreenModal>
|
||||
</FullScreenModal>
|
||||
{/if}
|
||||
|
||||
{#if selectedRemoveUser}
|
||||
<ConfirmDialog
|
||||
title={$t('album_remove_user')}
|
||||
prompt={$t('album_remove_user_confirmation', { values: { user: selectedRemoveUser.name } })}
|
||||
confirmText={$t('remove_user')}
|
||||
onConfirm={handleRemoveUser}
|
||||
onCancel={() => (selectedRemoveUser = null)}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -345,7 +345,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveUser = async (userId: string) => {
|
||||
const handleRemoveUser = async (userId: string, nextViewMode: ViewMode) => {
|
||||
if (userId == 'me' || userId === $user.id) {
|
||||
await goto(backUrl);
|
||||
return;
|
||||
@ -353,7 +353,9 @@
|
||||
|
||||
try {
|
||||
await refreshAlbum();
|
||||
viewMode = album.albumUsers.length > 0 ? ViewMode.VIEW_USERS : ViewMode.VIEW;
|
||||
|
||||
// Dynamically set the view mode based on the passed argument
|
||||
viewMode = album.albumUsers.length > 0 ? nextViewMode : ViewMode.VIEW;
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.error_deleting_shared_user'));
|
||||
}
|
||||
@ -730,7 +732,7 @@
|
||||
<ShareInfoModal
|
||||
onClose={() => (viewMode = ViewMode.VIEW)}
|
||||
{album}
|
||||
onRemove={handleRemoveUser}
|
||||
onRemove={(userId) => handleRemoveUser(userId, ViewMode.VIEW_USERS)}
|
||||
onRefreshAlbum={refreshAlbum}
|
||||
/>
|
||||
{/if}
|
||||
@ -744,6 +746,7 @@
|
||||
albumOrder = order;
|
||||
await setModeToView();
|
||||
}}
|
||||
onRemove={(userId) => handleRemoveUser(userId, ViewMode.OPTIONS)}
|
||||
onClose={() => (viewMode = ViewMode.VIEW)}
|
||||
onToggleEnabledActivity={handleToggleEnableActivity}
|
||||
onShowSelectSharedUser={() => (viewMode = ViewMode.SELECT_USERS)}
|
||||
|
Loading…
Reference in New Issue
Block a user