Skip to content

Commit

Permalink
add current user in editor header, fix permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
riccardoperra committed Nov 5, 2024
1 parent 3bec97a commit ffc54d3
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {style} from '@vanilla-extract/css';

export const badge = style({
width: '28px',
height: '28px',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
textAlign: 'center',
fontSize: '13px !important',
background: '#076a6e',
color: 'white',
borderRadius: '9999px',
});

export const currentUser = style({
fontSize: '14px !important',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {Icon} from '#ui/components/Icon';
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@codeui/kit';
import {useAction, useSubmission} from '@solidjs/router';
import type {Models} from 'appwrite';
import {Show} from 'solid-js';
import {logout, signupWithGithub} from '~/lib/session';
import {badge, currentUser} from './CurrentUser.css';
export interface CurrentUserBarProps {
user: Models.User<any> | null;
}

export function EditorHeaderCurrentUser(props: CurrentUserBarProps) {
const initials = (user: Models.User<any>) => {
if (user.name) {
const [firstName, lastName] = user.name.split(' ');
return [firstName, lastName]
.filter(Boolean)
.map(str => str.charAt(0))
.join('');
} else {
return '?';
}
};

const logoutAction = useAction(logout);

const isSignup = useSubmission(signupWithGithub);

return (
<Show
fallback={
<form action={signupWithGithub} method={'post'}>
<Button
variant={'ghost'}
theme={'secondary'}
size={'sm'}
type={'submit'}
loading={isSignup.pending}
>
Signup with Github
</Button>
</form>
}
when={props.user}
>
{user => (
<DropdownMenu>
<DropdownMenuTrigger
// @ts-expect-error TOOD: Fix @codeui/kit types
as={triggerProps => (
<Button
size={'sm'}
{...triggerProps}
class={currentUser}
variant={'ghost'}
theme={'secondary'}
/>
)}
>
<span class={badge}>{initials(user())}</span>
<Icon name={'keyboard_arrow_down'} />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
name="logout"
as={'button'}
onClick={() => {
logoutAction().then(() => window.location.reload());
}}
>
Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
</Show>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const subHeaderRightContent = style({
export const headerRightSide = style({
marginLeft: 'auto',
display: 'flex',
alignItems: 'center',
gap: appTheme.spacing['2'],
});

Expand Down
43 changes: 24 additions & 19 deletions packages/app/src/components/Editor/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {createScratchFork, updateScratch} from '../../../lib/scratchApi';
import {EditorContext} from '../editor.context';
import {EditorUiStore} from '../../../store/editor/ui.store';
import * as styles from './EditorHeader.css';
import {EditorHeaderCurrentUser} from './CurrentUser/CurrentUser';

export interface EditorHeaderProps {
showBack: boolean;
Expand Down Expand Up @@ -105,8 +106,8 @@ export function EditorHeader(props: EditorHeaderProps) {

{props.name}

<Show when={user()}>
<div class={styles.headerRightSide}>
<div class={styles.headerRightSide}>
<Show when={user()}>
<Show
fallback={
<>
Expand All @@ -116,26 +117,30 @@ export function EditorHeader(props: EditorHeaderProps) {
when={editorStore.get.remoteId}
>
{remoteId => (
<form
action={updateScratch.with(
remoteId(),
editorStore.yamlSession.source(),
)}
method={'post'}
>
<Button
type={'submit'}
theme={'primary'}
size={'sm'}
loading={isUpdating.pending}
<Show when={editorStore.scratch()?.canEdit}>
<form
action={updateScratch.with(
remoteId(),
editorStore.yamlSession.source(),
)}
method={'post'}
>
Save
</Button>
</form>
<Button
type={'submit'}
theme={'primary'}
size={'sm'}
loading={isUpdating.pending}
>
Save
</Button>
</form>
</Show>
)}
</Show>
</div>
</Show>
</Show>

<EditorHeaderCurrentUser user={user() ?? null} />
</div>
</header>
<div class={styles.subHeader}>
<EditorHeaderActionButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import {updateScratchName} from '~/lib/scratchApi';
import {Icon} from '~/ui/components/Icon';
import {useEditorContext} from '../editor.context';
import * as confirmPopoverStyles from '~/ui/components/ConfirmPopover/ConfirmPopover.css';
import {provideState} from 'statebuilder';
import {EditorStore} from '~/store/editor/editor.store';

export function EditorRepositoryHeaderScratch() {
const editor = useEditorContext()!;
const editorStore = provideState(EditorStore);
const [editing, setEditing] = createSignal(false);

const renamingScratch = useAction(updateScratchName);
Expand All @@ -25,47 +28,49 @@ export function EditorRepositoryHeaderScratch() {
{scratch => (
<span>
{scratch().name}.yml
<Popover open={editing()} onOpenChange={setEditing}>
<PopoverTrigger
as={triggerProps => (
<IconButton
aria-label="Rename"
size={'xs'}
variant={'ghost'}
theme={'secondary'}
{...triggerProps}
/>
)}
>
<Icon name={'edit'} />
</PopoverTrigger>
<PopoverContent>
<form
onSubmit={e => {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
renamingScratch(
editor.remoteId!,
data.get('name') as string,
).finally(() => {
setEditing(false);
});
}}
<Show when={editorStore.canEditCurrent()}>
<Popover open={editing()} onOpenChange={setEditing}>
<PopoverTrigger
as={triggerProps => (
<IconButton
aria-label="Rename"
size={'xs'}
variant={'ghost'}
theme={'secondary'}
{...triggerProps}
/>
)}
>
<TextField name={'name'} defaultValue={scratch().name} />
<div class={confirmPopoverStyles.contentFooter}>
<Button
type={'submit'}
size="xs"
theme={'primary'}
loading={renamingScratchSubsmission.pending}
>
Rename
</Button>
</div>
</form>
</PopoverContent>
</Popover>
<Icon name={'edit'} />
</PopoverTrigger>
<PopoverContent>
<form
onSubmit={e => {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
renamingScratch(
editor.remoteId!,
data.get('name') as string,
).finally(() => {
setEditing(false);
});
}}
>
<TextField name={'name'} defaultValue={scratch().name} />
<div class={confirmPopoverStyles.contentFooter}>
<Button
type={'submit'}
size="xs"
theme={'primary'}
loading={renamingScratchSubsmission.pending}
>
Rename
</Button>
</div>
</form>
</PopoverContent>
</Popover>
</Show>
</span>
)}
</Show>
Expand Down
18 changes: 14 additions & 4 deletions packages/app/src/store/editor/editor.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,28 +96,38 @@ export const EditorStore = defineStore<EditorState>(() => ({
};
})
.extend((_, context) => {
const editorContext = useContext(EditorContext)!;

context.hooks.onInit(() => {
const context = useContext(EditorContext)!;
// Support reactivity when using hybrid routing
createEffect(
on(
() => context.source,
() => editorContext.source,
source => {
_.initEditSession(context.source).then();
_.initEditSession(editorContext.source).then();
},
// {defer: true},
),
);

createEffect(
on(
() => context.remoteId,
() => editorContext.remoteId,
remoteId => {
_.set('remoteId', remoteId);
},
),
);
});

return {
scratch() {
return editorContext.scratch?.();
},
canEditCurrent() {
return editorContext.scratch?.()?.canEdit === true;
},
};
})
.extend(
withProxyCommands<{
Expand Down

0 comments on commit ffc54d3

Please sign in to comment.