Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Omn-190] - [Settings View] - Labels #345

Merged
merged 51 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
11db7be
[Omn-190] - [Settings View] - Labels
gitstart Mar 30, 2022
72e68b2
Update the font and background colour on label chips
jacksonh Mar 30, 2022
e478b01
Update label import, use LabelChip instead of styled text to display …
jacksonh Mar 30, 2022
f4a0376
Consistent font sizes for headlines
jacksonh Mar 30, 2022
2c15516
Order labels by createdAt so they maintain a consistent order
jacksonh Mar 30, 2022
edc5d6a
Fix label import for old location, apply the theme on the page
jacksonh Mar 30, 2022
a8faaf8
Remove debug sort on labels
jacksonh Mar 30, 2022
88c96c8
Remove the DotsSix since we dont support re-ordering these items
jacksonh Mar 30, 2022
a0ef2fd
Dont use isDarkMode, use themed color for setting icon colors
jacksonh Mar 31, 2022
d07f8c6
Merge commit '7bdeceded43f70472dbc60a21bc3a507aff87958' into OMN-190
gitstart Mar 31, 2022
1978a92
Effected review corrections
gitstart Mar 31, 2022
92925b6
Prettier fixes
jacksonh Apr 3, 2022
85b2473
Upgrade yarn.lock
jacksonh Apr 3, 2022
a99ab36
Remove unused import
jacksonh Apr 4, 2022
927044f
Update Label import
jacksonh Apr 5, 2022
287b208
Comment out EditLabelsModal while we merge
jacksonh Apr 5, 2022
b322add
Use a single Plus icon
jacksonh Apr 5, 2022
f765303
Dont use action buttons on desktop
jacksonh Apr 5, 2022
099cf57
Have a distinct edit/view mode for the colour buttons
jacksonh Apr 5, 2022
1c9161a
Remove border on dropdown which causes UI to move around
jacksonh Apr 5, 2022
7ba7a55
Always display the add label button
jacksonh Apr 5, 2022
a8ce211
Remove the title bar, always display rounding on the top item
jacksonh Apr 5, 2022
52d1d76
In mobile mode align action buttons to the right
jacksonh Apr 5, 2022
8439be6
Move + button up on mobile, consistent design for labels and emails
jacksonh Apr 5, 2022
6d5159b
Smaller padding on mobile action buttons
jacksonh Apr 5, 2022
cdc7d62
Update colours when changing values
jacksonh Apr 5, 2022
3bb7262
Remove extra vars
jacksonh Apr 5, 2022
8da027a
Remove unused
jacksonh Apr 5, 2022
07bc512
Hide the menu button when in edit mode
jacksonh Apr 5, 2022
8a7446f
edit mode for labels on mobile
jacksonh Apr 5, 2022
239a283
Darken the border on label chips
jacksonh Apr 5, 2022
0ffc064
Use the MobileEdit layout for editing labels
jacksonh Apr 5, 2022
db7b499
Remove hover background colour
jacksonh Apr 5, 2022
cdd950f
With new layout we can always display colour text
jacksonh Apr 5, 2022
b403be5
Padding at bottom, rounded corners when editing top/bottom labels
jacksonh Apr 5, 2022
32d16a6
Set a random color when creating a new label
jacksonh Apr 6, 2022
e49bb86
Use new layout for desktop labels, handle API errors
jacksonh Apr 6, 2022
09ee5d3
Standardize info link
jacksonh Apr 6, 2022
e75af31
Add key prop to generic label
jacksonh Apr 6, 2022
06360a5
Merge branch 'main' into OMN-190
jacksonh Apr 6, 2022
1cdb775
Update typeorm usage
jacksonh Apr 6, 2022
b7dbae6
Update placeholder text
jacksonh Apr 6, 2022
1bac061
Update volta version
jacksonh Apr 6, 2022
63a374b
package syntax
jacksonh Apr 6, 2022
26bff1b
Pin yarn version w/volta
jacksonh Apr 6, 2022
aabd9ea
Shorten the text
jacksonh Apr 6, 2022
57f865c
Update to typeorm 0.3
jacksonh Apr 6, 2022
53c536f
Move toast to bottom right
jacksonh Apr 6, 2022
48ca138
Prettier fixes
jacksonh Apr 6, 2022
a68a5fb
Labels are ordered by creation time in API now
jacksonh Apr 6, 2022
8670bbb
Remove debug statements
jacksonh Apr 6, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"node": "14.18.x"
},
"volta": {
"node": "14.18.x"
"node": "14.18.1",
"yarn": "1.22.18"
}
}
59 changes: 59 additions & 0 deletions packages/api/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ export type Mutation = {
signup: SignupResult;
updateHighlight: UpdateHighlightResult;
updateHighlightReply: UpdateHighlightReplyResult;
updateLabel: UpdateLabelResult;
updateLinkShareInfo: UpdateLinkShareInfoResult;
updateReminder: UpdateReminderResult;
updateSharedComment: UpdateSharedCommentResult;
Expand Down Expand Up @@ -966,6 +967,11 @@ export type MutationUpdateHighlightReplyArgs = {
};


export type MutationUpdateLabelArgs = {
input: UpdateLabelInput;
};


export type MutationUpdateLinkShareInfoArgs = {
input: UpdateLinkShareInfoInput;
};
Expand Down Expand Up @@ -1577,6 +1583,32 @@ export type UpdateHighlightSuccess = {
highlight: Highlight;
};

export type UpdateLabelError = {
__typename?: 'UpdateLabelError';
errorCodes: Array<UpdateLabelErrorCode>;
};

export enum UpdateLabelErrorCode {
BadRequest = 'BAD_REQUEST',
Forbidden = 'FORBIDDEN',
NotFound = 'NOT_FOUND',
Unauthorized = 'UNAUTHORIZED'
}

export type UpdateLabelInput = {
color: Scalars['String'];
description?: InputMaybe<Scalars['String']>;
labelId: Scalars['ID'];
name: Scalars['String'];
};

export type UpdateLabelResult = UpdateLabelError | UpdateLabelSuccess;

export type UpdateLabelSuccess = {
__typename?: 'UpdateLabelSuccess';
label: Label;
};

export type UpdateLinkShareInfoError = {
__typename?: 'UpdateLinkShareInfoError';
errorCodes: Array<UpdateLinkShareInfoErrorCode>;
Expand Down Expand Up @@ -2095,6 +2127,11 @@ export type ResolversTypes = {
UpdateHighlightReplySuccess: ResolverTypeWrapper<UpdateHighlightReplySuccess>;
UpdateHighlightResult: ResolversTypes['UpdateHighlightError'] | ResolversTypes['UpdateHighlightSuccess'];
UpdateHighlightSuccess: ResolverTypeWrapper<UpdateHighlightSuccess>;
UpdateLabelError: ResolverTypeWrapper<UpdateLabelError>;
UpdateLabelErrorCode: UpdateLabelErrorCode;
UpdateLabelInput: UpdateLabelInput;
UpdateLabelResult: ResolversTypes['UpdateLabelError'] | ResolversTypes['UpdateLabelSuccess'];
UpdateLabelSuccess: ResolverTypeWrapper<UpdateLabelSuccess>;
UpdateLinkShareInfoError: ResolverTypeWrapper<UpdateLinkShareInfoError>;
UpdateLinkShareInfoErrorCode: UpdateLinkShareInfoErrorCode;
UpdateLinkShareInfoInput: UpdateLinkShareInfoInput;
Expand Down Expand Up @@ -2326,6 +2363,10 @@ export type ResolversParentTypes = {
UpdateHighlightReplySuccess: UpdateHighlightReplySuccess;
UpdateHighlightResult: ResolversParentTypes['UpdateHighlightError'] | ResolversParentTypes['UpdateHighlightSuccess'];
UpdateHighlightSuccess: UpdateHighlightSuccess;
UpdateLabelError: UpdateLabelError;
UpdateLabelInput: UpdateLabelInput;
UpdateLabelResult: ResolversParentTypes['UpdateLabelError'] | ResolversParentTypes['UpdateLabelSuccess'];
UpdateLabelSuccess: UpdateLabelSuccess;
UpdateLinkShareInfoError: UpdateLinkShareInfoError;
UpdateLinkShareInfoInput: UpdateLinkShareInfoInput;
UpdateLinkShareInfoResult: ResolversParentTypes['UpdateLinkShareInfoError'] | ResolversParentTypes['UpdateLinkShareInfoSuccess'];
Expand Down Expand Up @@ -2937,6 +2978,7 @@ export type MutationResolvers<ContextType = ResolverContext, ParentType extends
signup?: Resolver<ResolversTypes['SignupResult'], ParentType, ContextType, RequireFields<MutationSignupArgs, 'input'>>;
updateHighlight?: Resolver<ResolversTypes['UpdateHighlightResult'], ParentType, ContextType, RequireFields<MutationUpdateHighlightArgs, 'input'>>;
updateHighlightReply?: Resolver<ResolversTypes['UpdateHighlightReplyResult'], ParentType, ContextType, RequireFields<MutationUpdateHighlightReplyArgs, 'input'>>;
updateLabel?: Resolver<ResolversTypes['UpdateLabelResult'], ParentType, ContextType, RequireFields<MutationUpdateLabelArgs, 'input'>>;
updateLinkShareInfo?: Resolver<ResolversTypes['UpdateLinkShareInfoResult'], ParentType, ContextType, RequireFields<MutationUpdateLinkShareInfoArgs, 'input'>>;
updateReminder?: Resolver<ResolversTypes['UpdateReminderResult'], ParentType, ContextType, RequireFields<MutationUpdateReminderArgs, 'input'>>;
updateSharedComment?: Resolver<ResolversTypes['UpdateSharedCommentResult'], ParentType, ContextType, RequireFields<MutationUpdateSharedCommentArgs, 'input'>>;
Expand Down Expand Up @@ -3257,6 +3299,20 @@ export type UpdateHighlightSuccessResolvers<ContextType = ResolverContext, Paren
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type UpdateLabelErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['UpdateLabelError'] = ResolversParentTypes['UpdateLabelError']> = {
errorCodes?: Resolver<Array<ResolversTypes['UpdateLabelErrorCode']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type UpdateLabelResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['UpdateLabelResult'] = ResolversParentTypes['UpdateLabelResult']> = {
__resolveType: TypeResolveFn<'UpdateLabelError' | 'UpdateLabelSuccess', ParentType, ContextType>;
};

export type UpdateLabelSuccessResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['UpdateLabelSuccess'] = ResolversParentTypes['UpdateLabelSuccess']> = {
label?: Resolver<ResolversTypes['Label'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type UpdateLinkShareInfoErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['UpdateLinkShareInfoError'] = ResolversParentTypes['UpdateLinkShareInfoError']> = {
errorCodes?: Resolver<Array<ResolversTypes['UpdateLinkShareInfoErrorCode']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
Expand Down Expand Up @@ -3551,6 +3607,9 @@ export type Resolvers<ContextType = ResolverContext> = {
UpdateHighlightReplySuccess?: UpdateHighlightReplySuccessResolvers<ContextType>;
UpdateHighlightResult?: UpdateHighlightResultResolvers<ContextType>;
UpdateHighlightSuccess?: UpdateHighlightSuccessResolvers<ContextType>;
UpdateLabelError?: UpdateLabelErrorResolvers<ContextType>;
UpdateLabelResult?: UpdateLabelResultResolvers<ContextType>;
UpdateLabelSuccess?: UpdateLabelSuccessResolvers<ContextType>;
UpdateLinkShareInfoError?: UpdateLinkShareInfoErrorResolvers<ContextType>;
UpdateLinkShareInfoResult?: UpdateLinkShareInfoResultResolvers<ContextType>;
UpdateLinkShareInfoSuccess?: UpdateLinkShareInfoSuccessResolvers<ContextType>;
Expand Down
25 changes: 25 additions & 0 deletions packages/api/src/generated/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ type Mutation {
signup(input: SignupInput!): SignupResult!
updateHighlight(input: UpdateHighlightInput!): UpdateHighlightResult!
updateHighlightReply(input: UpdateHighlightReplyInput!): UpdateHighlightReplyResult!
updateLabel(input: UpdateLabelInput!): UpdateLabelResult!
updateLinkShareInfo(input: UpdateLinkShareInfoInput!): UpdateLinkShareInfoResult!
updateReminder(input: UpdateReminderInput!): UpdateReminderResult!
updateSharedComment(input: UpdateSharedCommentInput!): UpdateSharedCommentResult!
Expand Down Expand Up @@ -1194,6 +1195,30 @@ type UpdateHighlightSuccess {
highlight: Highlight!
}

type UpdateLabelError {
errorCodes: [UpdateLabelErrorCode!]!
}

enum UpdateLabelErrorCode {
BAD_REQUEST
FORBIDDEN
NOT_FOUND
UNAUTHORIZED
}

input UpdateLabelInput {
color: String!
description: String
labelId: ID!
name: String!
}

union UpdateLabelResult = UpdateLabelError | UpdateLabelSuccess

type UpdateLabelSuccess {
label: Label!
}

type UpdateLinkShareInfoError {
errorCodes: [UpdateLinkShareInfoErrorCode!]!
}
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/resolvers/function_resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import {
updateUserResolver,
uploadFileRequestResolver,
validateUsernameResolver,
updateLabelResolver,
} from './index'
import { getShareInfoForArticle } from '../datalayer/links/share_info'
import {
Expand Down Expand Up @@ -132,6 +133,7 @@ export const functionResolvers = {
deleteReminder: deleteReminderResolver,
setDeviceToken: setDeviceTokenResolver,
createLabel: createLabelResolver,
updateLabel: updateLabelResolver,
deleteLabel: deleteLabelResolver,
login: loginResolver,
signup: signupResolver,
Expand Down
73 changes: 73 additions & 0 deletions packages/api/src/resolvers/labels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ import {
MutationCreateLabelArgs,
MutationDeleteLabelArgs,
MutationSetLabelsArgs,
MutationUpdateLabelArgs,
SetLabelsError,
SetLabelsErrorCode,
SetLabelsSuccess,
UpdateLabelError,
UpdateLabelErrorCode,
UpdateLabelSuccess,
} from '../../generated/graphql'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
Expand Down Expand Up @@ -42,6 +46,11 @@ export const labelsResolver = authorized<LabelsSuccess, LabelsError>(
const user = await getRepository(User).findOne({
where: { id: uid },
relations: ['labels'],
order: {
labels: {
createdAt: 'DESC',
},
},
})
if (!user) {
return {
Expand Down Expand Up @@ -249,3 +258,67 @@ export const setLabelsResolver = authorized<
}
}
})

export const updateLabelResolver = authorized<
UpdateLabelSuccess,
UpdateLabelError,
MutationUpdateLabelArgs
>(async (_, { input }, { claims: { uid }, log }) => {
log.info('updateLabelResolver')

try {
const { name, color, description, labelId } = input
const user = await getRepository(User).findOneBy({ id: uid })
if (!user) {
return {
errorCodes: [UpdateLabelErrorCode.Unauthorized],
}
}

const label = await getRepository(Label).findOne({
where: { id: labelId },
relations: ['user'],
})
if (!label) {
return {
errorCodes: [UpdateLabelErrorCode.NotFound],
}
}

const result = await AppDataSource.transaction(async (t) => {
await setClaims(t, uid)
return await t.getRepository(Label).update(
{ id: labelId },
{
name: name,
description: description || undefined,
color: color,
}
)
})

log.info('Updating a label', {
result,
labels: {
source: 'resolver',
resolver: 'updateLabelResolver',
},
})

if (!result) {
log.info('failed to update')
return {
errorCodes: [UpdateLabelErrorCode.BadRequest],
}
}

log.info('updated successfully')

return { label: label }
} catch (error) {
log.error('error updating label', error)
return {
errorCodes: [UpdateLabelErrorCode.BadRequest],
}
}
})
25 changes: 25 additions & 0 deletions packages/api/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,30 @@ const schema = gql`

union DeleteLabelResult = DeleteLabelSuccess | DeleteLabelError

input UpdateLabelInput {
labelId: ID!
color: String!
description: String
name: String!
}

type UpdateLabelSuccess {
label: Label!
}

enum UpdateLabelErrorCode {
UNAUTHORIZED
BAD_REQUEST
NOT_FOUND
FORBIDDEN
}

type UpdateLabelError {
errorCodes: [UpdateLabelErrorCode!]!
}

union UpdateLabelResult = UpdateLabelSuccess | UpdateLabelError

input LoginInput {
password: String!
email: String!
Expand Down Expand Up @@ -1410,6 +1434,7 @@ const schema = gql`
deleteReminder(id: ID!): DeleteReminderResult!
setDeviceToken(input: SetDeviceTokenInput!): SetDeviceTokenResult!
createLabel(input: CreateLabelInput!): CreateLabelResult!
updateLabel(input: UpdateLabelInput!): UpdateLabelResult!
deleteLabel(id: ID!): DeleteLabelResult!
login(input: LoginInput!): LoginResult!
signup(input: SignupInput!): SignupResult!
Expand Down
2 changes: 1 addition & 1 deletion packages/api/test/resolvers/labels.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('Labels API', () => {
user: { id: user.id },
})
expect(res.body.data.labels.labels).to.eql(
labels.map((label) => ({
labels.reverse().map((label) => ({
id: label.id,
name: label.name,
color: label.color,
Expand Down
17 changes: 13 additions & 4 deletions packages/web/components/elements/DropdownElements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Arrow,
Label,
} from '@radix-ui/react-dropdown-menu'
import { CSS } from '@stitches/react';
import { styled } from './../tokens/stitches.config'

const itemStyles = {
Expand Down Expand Up @@ -43,7 +44,7 @@ const StyledTriggerItem = styled(TriggerItem, {
...itemStyles,
})

const DropdownContent = styled(Content, {
export const DropdownContent = styled(Content, {
minWidth: 130,
backgroundColor: '$grayBg',
borderRadius: '0.5em',
Expand All @@ -70,12 +71,16 @@ type DropdownProps = {
showArrow?: boolean
triggerElement: React.ReactNode
children: React.ReactNode
styledArrow?: boolean
align?: DropdownAlignment
disabled?: boolean
css?: CSS
}

export const DropdownSeparator = styled(Separator, {
height: 0,
height: '1px',
margin: 0,
backgroundColor: '$grayBorder',
})

type DropdownOptionProps = {
Expand All @@ -91,6 +96,7 @@ export function DropdownOption(props: DropdownOptionProps): JSX.Element {
<StyledItem onSelect={props.onSelect}>
{props.title ?? props.children}
</StyledItem>
{props.hideSeparator ? null : <DropdownSeparator />}
</>
)
}
Expand All @@ -101,12 +107,15 @@ export function Dropdown({
triggerElement,
labelText,
showArrow = true,
disabled = false,
css
}: DropdownProps): JSX.Element {
return (
<Root modal={false}>
<DropdownTrigger>{triggerElement}</DropdownTrigger>
<DropdownTrigger disabled={disabled}>{triggerElement}</DropdownTrigger>
<DropdownContent
onInteractOutside={() => {
css={css}
onInteractOutside={(event) => {
// remove focus from dropdown
;(document.activeElement as HTMLElement).blur()
}}
Expand Down