feat: projects can be set to public
This commit is contained in:
parent
3e72271d9b
commit
04c12e4da9
@ -30,6 +30,7 @@
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }],
|
||||
"react/require-default-props": "off",
|
||||
"no-case-declarations": "off",
|
||||
"no-plusplus": "off",
|
||||
"react/prop-types": 0,
|
||||
|
@ -24,7 +24,7 @@
|
||||
"@types/react-router-dom": "^5.1.3",
|
||||
"@types/react-select": "^3.0.13",
|
||||
"@types/react-timeago": "^4.1.1",
|
||||
"@types/styled-components": "^5.0.0",
|
||||
"@types/styled-components": "^5.1.0",
|
||||
"apollo-cache-inmemory": "^1.6.5",
|
||||
"apollo-client": "^2.6.8",
|
||||
"apollo-link": "^1.2.13",
|
||||
@ -64,7 +64,7 @@
|
||||
"react-timeago": "^4.4.0",
|
||||
"react-toastify": "^6.0.8",
|
||||
"rich-markdown-editor": "^10.6.5",
|
||||
"styled-components": "^5.0.1",
|
||||
"styled-components": "^5.1.0",
|
||||
"typescript": "~3.7.2"
|
||||
},
|
||||
"proxy": "http://localhost:3333",
|
||||
@ -93,10 +93,10 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^1.13.2",
|
||||
"@graphql-codegen/typescript": "^1.13.2",
|
||||
"@graphql-codegen/typescript-operations": "^1.13.2",
|
||||
"@graphql-codegen/typescript-react-apollo": "^1.13.2",
|
||||
"@graphql-codegen/cli": "^1.21.4",
|
||||
"@graphql-codegen/typescript": "^1.22.0",
|
||||
"@graphql-codegen/typescript-operations": "^1.17.16",
|
||||
"@graphql-codegen/typescript-react-apollo": "^2.2.4",
|
||||
"@typescript-eslint/eslint-plugin": "^2.20.0",
|
||||
"@typescript-eslint/parser": "^2.20.0",
|
||||
"eslint": "^6.8.0",
|
||||
|
@ -41,9 +41,7 @@ const AuthorizedRoutes = () => {
|
||||
const { status } = x;
|
||||
const response: ValidateTokenResponse = await x.json();
|
||||
const { valid, userID } = response;
|
||||
if (!valid) {
|
||||
history.replace(`/login`);
|
||||
} else {
|
||||
if (valid) {
|
||||
setUser(userID);
|
||||
}
|
||||
setLoading(false);
|
||||
|
@ -1,17 +1,28 @@
|
||||
import React from 'react';
|
||||
import ProjectSettings, { DeleteConfirm, DELETE_INFO } from 'shared/components/ProjectSettings';
|
||||
import { useDeleteProjectMutation, GetProjectsDocument } from 'shared/generated/graphql';
|
||||
import React, { useState } from 'react';
|
||||
import ProjectSettings, { DeleteConfirm, DELETE_INFO, PublicConfirm } from 'shared/components/ProjectSettings';
|
||||
import {
|
||||
useDeleteProjectMutation,
|
||||
GetProjectsDocument,
|
||||
useToggleProjectVisibilityMutation,
|
||||
} from 'shared/generated/graphql';
|
||||
import { usePopup, Popup } from 'shared/components/PopupMenu';
|
||||
import produce from 'immer';
|
||||
|
||||
type ProjectPopupProps = {
|
||||
history: any;
|
||||
name: string;
|
||||
publicOn: string | null;
|
||||
projectID: string;
|
||||
};
|
||||
|
||||
const ProjectPopup: React.FC<ProjectPopupProps> = ({ history, name, projectID }) => {
|
||||
const ProjectPopup: React.FC<ProjectPopupProps> = ({ history, name, projectID, publicOn: initialPublicOn }) => {
|
||||
const { hidePopup, setTab } = usePopup();
|
||||
const [publicOn, setPublicOn] = useState(initialPublicOn);
|
||||
const [toggleProjectVisibility] = useToggleProjectVisibilityMutation({
|
||||
onCompleted: data => {
|
||||
setPublicOn(data.toggleProjectVisibility.project.publicOn);
|
||||
},
|
||||
});
|
||||
const [deleteProject] = useDeleteProjectMutation({
|
||||
update: (client, deleteData) => {
|
||||
const cacheData: any = client.readQuery({
|
||||
@ -36,11 +47,28 @@ const ProjectPopup: React.FC<ProjectPopupProps> = ({ history, name, projectID })
|
||||
<>
|
||||
<Popup title={null} tab={0}>
|
||||
<ProjectSettings
|
||||
publicOn={publicOn}
|
||||
onToggleProjectVisible={visible => {
|
||||
if (visible) {
|
||||
setTab(2, { width: 300 });
|
||||
} else {
|
||||
toggleProjectVisibility({ variables: { projectID, isPublic: false } });
|
||||
}
|
||||
}}
|
||||
onDeleteProject={() => {
|
||||
setTab(1, { width: 300 });
|
||||
}}
|
||||
/>
|
||||
</Popup>
|
||||
<Popup title="Change to public?" tab={1}>
|
||||
<PublicConfirm
|
||||
onConfirm={() => {
|
||||
if (projectID) {
|
||||
toggleProjectVisibility({ variables: { projectID, isPublic: true } });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Popup>
|
||||
<Popup title={`Delete the "${name}" project?`} tab={1}>
|
||||
<DeleteConfirm
|
||||
description={DELETE_INFO.DELETE_PROJECTS.description}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import TopNavbar, { MenuItem } from 'shared/components/TopNavbar';
|
||||
import LoggedOutNavbar from 'shared/components/TopNavbar/LoggedOut';
|
||||
import { ProfileMenu } from 'shared/components/DropdownMenu';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useCurrentUser } from 'App/context';
|
||||
@ -11,6 +12,8 @@ import NotificationPopup, { NotificationItem } from 'shared/components/Notifcati
|
||||
import theme from 'App/ThemeStyles';
|
||||
import ProjectFinder from './ProjectFinder';
|
||||
|
||||
// TODO: Move to context based navbar?
|
||||
|
||||
type GlobalTopNavbarProps = {
|
||||
nameOnly?: boolean;
|
||||
projectID: string | null;
|
||||
@ -30,7 +33,7 @@ type GlobalTopNavbarProps = {
|
||||
onRemoveInvitedFromBoard?: (email: string) => void;
|
||||
};
|
||||
|
||||
const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
const LoggedInNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
currentTab,
|
||||
onSetTab,
|
||||
menuType,
|
||||
@ -46,9 +49,9 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
onRemoveInvitedFromBoard,
|
||||
onRemoveFromBoard,
|
||||
}) => {
|
||||
const { user, setUser } = useCurrentUser();
|
||||
const { data } = useTopNavbarQuery();
|
||||
const { showPopup, hidePopup } = usePopup();
|
||||
const { setUser } = useCurrentUser();
|
||||
const history = useHistory();
|
||||
const onLogout = () => {
|
||||
fetch('/auth/logout', {
|
||||
@ -109,9 +112,6 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
// TODO: readd permision check
|
||||
// const userIsTeamOrProjectAdmin = user.isAdmin(PermissionLevel.TEAM, PermissionObjectType.TEAM, teamID);
|
||||
const userIsTeamOrProjectAdmin = true;
|
||||
@ -174,6 +174,8 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const user = data ? data.me?.user : null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<TopNavbar
|
||||
@ -188,7 +190,7 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
);
|
||||
}}
|
||||
currentTab={currentTab}
|
||||
user={data ? data.me.user : null}
|
||||
user={user ?? null}
|
||||
canEditProjectName={userIsTeamOrProjectAdmin}
|
||||
canInviteUser={userIsTeamOrProjectAdmin}
|
||||
onMemberProfile={onMemberProfile}
|
||||
@ -215,4 +217,45 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
|
||||
currentTab,
|
||||
onSetTab,
|
||||
menuType,
|
||||
teamID,
|
||||
onChangeProjectOwner,
|
||||
onChangeRole,
|
||||
name,
|
||||
popupContent,
|
||||
projectMembers,
|
||||
projectInvitedMembers,
|
||||
onInviteUser,
|
||||
onSaveProjectName,
|
||||
onRemoveInvitedFromBoard,
|
||||
onRemoveFromBoard,
|
||||
}) => {
|
||||
const { user } = useCurrentUser();
|
||||
if (user) {
|
||||
return (
|
||||
<LoggedInNavbar
|
||||
currentTab={currentTab}
|
||||
projectID={null}
|
||||
onSetTab={onSetTab}
|
||||
menuType={menuType}
|
||||
teamID={teamID}
|
||||
onChangeRole={onChangeRole}
|
||||
onChangeProjectOwner={onChangeProjectOwner}
|
||||
name={name}
|
||||
popupContent={popupContent}
|
||||
projectMembers={projectMembers}
|
||||
projectInvitedMembers={projectInvitedMembers}
|
||||
onInviteUser={onInviteUser}
|
||||
onSaveProjectName={onSaveProjectName}
|
||||
onRemoveInvitedFromBoard={onRemoveInvitedFromBoard}
|
||||
onRemoveFromBoard={onRemoveFromBoard}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <LoggedOutNavbar name={name} menuType={menuType} />;
|
||||
};
|
||||
|
||||
export default GlobalTopNavbar;
|
||||
|
@ -62,7 +62,7 @@ const Projects = () => {
|
||||
}}
|
||||
/>
|
||||
<GlobalTopNavbar projectID={null} onSaveProjectName={NOOP} name={null} />
|
||||
{!loading && data && (
|
||||
{!loading && data && data.me && (
|
||||
<Settings
|
||||
profile={data.me.user}
|
||||
onProfileAvatarChange={() => {
|
||||
|
@ -198,6 +198,7 @@ type ProjectBoardProps = {
|
||||
};
|
||||
|
||||
export const BoardLoading = () => {
|
||||
const { user } = useCurrentUser();
|
||||
return (
|
||||
<>
|
||||
<ProjectBar>
|
||||
@ -215,20 +216,22 @@ export const BoardLoading = () => {
|
||||
<ProjectActionText>Filter</ProjectActionText>
|
||||
</ProjectAction>
|
||||
</ProjectActions>
|
||||
<ProjectActions>
|
||||
<ProjectAction>
|
||||
<Tags width={13} height={13} />
|
||||
<ProjectActionText>Labels</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<ToggleOn width={13} height={13} />
|
||||
<ProjectActionText>Fields</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<Bolt width={13} height={13} />
|
||||
<ProjectActionText>Rules</ProjectActionText>
|
||||
</ProjectAction>
|
||||
</ProjectActions>
|
||||
{user && (
|
||||
<ProjectActions>
|
||||
<ProjectAction>
|
||||
<Tags width={13} height={13} />
|
||||
<ProjectActionText>Labels</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<ToggleOn width={13} height={13} />
|
||||
<ProjectActionText>Fields</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<Bolt width={13} height={13} />
|
||||
<ProjectActionText>Rules</ProjectActionText>
|
||||
</ProjectAction>
|
||||
</ProjectActions>
|
||||
)}
|
||||
</ProjectBar>
|
||||
<EmptyBoard />
|
||||
</>
|
||||
@ -469,7 +472,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
|
||||
}
|
||||
return 'All Tasks';
|
||||
};
|
||||
if (data && user) {
|
||||
if (data) {
|
||||
labelsRef.current = data.findProject.labels;
|
||||
membersRef.current = data.findProject.members;
|
||||
const onQuickEditorOpen = ($target: React.RefObject<HTMLElement>, taskID: string, taskGroupID: string) => {
|
||||
@ -570,34 +573,37 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
|
||||
);
|
||||
})}
|
||||
</ProjectActions>
|
||||
<ProjectActions>
|
||||
<ProjectAction
|
||||
onClick={$labelsRef => {
|
||||
showPopup(
|
||||
$labelsRef,
|
||||
<LabelManagerEditor
|
||||
taskLabels={null}
|
||||
labelColors={data.labelColors}
|
||||
labels={labelsRef}
|
||||
projectID={projectID ?? ''}
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Tags width={13} height={13} />
|
||||
<ProjectActionText>Labels</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<ToggleOn width={13} height={13} />
|
||||
<ProjectActionText>Fields</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<Bolt width={13} height={13} />
|
||||
<ProjectActionText>Rules</ProjectActionText>
|
||||
</ProjectAction>
|
||||
</ProjectActions>
|
||||
{user && (
|
||||
<ProjectActions>
|
||||
<ProjectAction
|
||||
onClick={$labelsRef => {
|
||||
showPopup(
|
||||
$labelsRef,
|
||||
<LabelManagerEditor
|
||||
taskLabels={null}
|
||||
labelColors={data.labelColors}
|
||||
labels={labelsRef}
|
||||
projectID={projectID ?? ''}
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Tags width={13} height={13} />
|
||||
<ProjectActionText>Labels</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<ToggleOn width={13} height={13} />
|
||||
<ProjectActionText>Fields</ProjectActionText>
|
||||
</ProjectAction>
|
||||
<ProjectAction disabled>
|
||||
<Bolt width={13} height={13} />
|
||||
<ProjectActionText>Rules</ProjectActionText>
|
||||
</ProjectAction>
|
||||
</ProjectActions>
|
||||
)}
|
||||
</ProjectBar>
|
||||
<SimpleLists
|
||||
isPublic={user === null}
|
||||
onTaskClick={task => {
|
||||
history.push(`${match.url}/c/${task.id}`);
|
||||
}}
|
||||
|
@ -424,7 +424,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||
updateTaskComment({ variables: { commentID, message } });
|
||||
}}
|
||||
editableComment={editableComment}
|
||||
me={data.me.user}
|
||||
me={data.me ? data.me.user : null}
|
||||
onCommentShowActions={(commentID, $targetRef) => {
|
||||
showPopup(
|
||||
$targetRef,
|
||||
|
@ -163,10 +163,6 @@ const Project = () => {
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
if (error) {
|
||||
history.push('/projects');
|
||||
}
|
||||
|
||||
if (data) {
|
||||
labelsRef.current = data.findProject.labels;
|
||||
|
||||
@ -204,7 +200,14 @@ const Project = () => {
|
||||
/>,
|
||||
);
|
||||
}}
|
||||
popupContent={<ProjectPopup history={history} name={data.findProject.name} projectID={projectID} />}
|
||||
popupContent={
|
||||
<ProjectPopup // eslint-disable-line
|
||||
history={history}
|
||||
publicOn={data.findProject.publicOn}
|
||||
name={data.findProject.name}
|
||||
projectID={projectID}
|
||||
/>
|
||||
}
|
||||
menuType={[{ name: 'Board', link: location.pathname }]}
|
||||
currentTab={0}
|
||||
projectMembers={data.findProject.members}
|
||||
|
@ -58,12 +58,14 @@ type Props = {
|
||||
onCardTitleChange?: (name: string) => void;
|
||||
labelVariant?: CardLabelVariant;
|
||||
toggleLabels?: boolean;
|
||||
isPublic?: boolean;
|
||||
toggleDirection?: 'shrink' | 'expand';
|
||||
};
|
||||
|
||||
const Card = React.forwardRef(
|
||||
(
|
||||
{
|
||||
isPublic = false,
|
||||
wrapperProps,
|
||||
onContextMenu,
|
||||
taskID,
|
||||
@ -120,9 +122,11 @@ const Card = React.forwardRef(
|
||||
}
|
||||
};
|
||||
const onTaskContext = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onOpenComposer();
|
||||
if (!isPublic) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onOpenComposer();
|
||||
}
|
||||
};
|
||||
const onOperationClick = (e: React.MouseEvent<HTMLOrSVGElement>) => {
|
||||
e.preventDefault();
|
||||
@ -145,7 +149,7 @@ const Card = React.forwardRef(
|
||||
{...wrapperProps}
|
||||
>
|
||||
<ListCardInnerContainer ref={$innerCardRef}>
|
||||
{isActive && !editable && (
|
||||
{!isPublic && isActive && !editable && (
|
||||
<ListCardOperation
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
|
@ -72,6 +72,9 @@ export const HeaderName = styled(TextareaAutosize)`
|
||||
box-shadow: none;
|
||||
font-weight: 600;
|
||||
margin: -4px 0;
|
||||
&:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
|
@ -24,6 +24,7 @@ type Props = {
|
||||
onOpenComposer: (id: string) => void;
|
||||
wrapperProps?: any;
|
||||
headerProps?: any;
|
||||
isPublic: boolean;
|
||||
index?: number;
|
||||
onExtraMenuOpen: (taskGroupID: string, $targetRef: React.RefObject<HTMLElement>) => void;
|
||||
};
|
||||
@ -37,6 +38,7 @@ const List = React.forwardRef(
|
||||
isComposerOpen,
|
||||
onOpenComposer,
|
||||
children,
|
||||
isPublic,
|
||||
wrapperProps,
|
||||
headerProps,
|
||||
onExtraMenuOpen,
|
||||
@ -86,39 +88,37 @@ const List = React.forwardRef(
|
||||
<Container ref={$wrapperRef} {...wrapperProps}>
|
||||
<Wrapper>
|
||||
<Header {...headerProps} isEditing={isEditingTitle}>
|
||||
<HeaderEditTarget onClick={onClick} isHidden={isEditingTitle} />
|
||||
{!isPublic && <HeaderEditTarget onClick={onClick} isHidden={isEditingTitle} />}
|
||||
<HeaderName
|
||||
ref={$listNameRef}
|
||||
disabled={isPublic}
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
spellCheck={false}
|
||||
value={listName}
|
||||
/>
|
||||
<ListExtraMenuButtonWrapper ref={$extraActionsRef} onClick={handleExtraMenuOpen}>
|
||||
<Ellipsis size={16} color="#c2c6dc" />
|
||||
</ListExtraMenuButtonWrapper>
|
||||
{!isPublic && (
|
||||
<ListExtraMenuButtonWrapper ref={$extraActionsRef} onClick={handleExtraMenuOpen}>
|
||||
<Ellipsis size={16} color="#c2c6dc" />
|
||||
</ListExtraMenuButtonWrapper>
|
||||
)}
|
||||
</Header>
|
||||
{children && children}
|
||||
<AddCardContainer hidden={isComposerOpen}>
|
||||
<AddCardButton onClick={() => onOpenComposer(id)}>
|
||||
<Plus width={12} height={12} />
|
||||
<AddCardButtonText>Add another card</AddCardButtonText>
|
||||
</AddCardButton>
|
||||
</AddCardContainer>
|
||||
{!isPublic && (
|
||||
<AddCardContainer hidden={isComposerOpen}>
|
||||
<AddCardButton onClick={() => onOpenComposer(id)}>
|
||||
<Plus width={12} height={12} />
|
||||
<AddCardButtonText>Add another card</AddCardButtonText>
|
||||
</AddCardButton>
|
||||
</AddCardContainer>
|
||||
)}
|
||||
</Wrapper>
|
||||
</Container>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
List.defaultProps = {
|
||||
children: null,
|
||||
isComposerOpen: false,
|
||||
wrapperProps: {},
|
||||
headerProps: {},
|
||||
};
|
||||
|
||||
List.displayName = 'List';
|
||||
export default List;
|
||||
|
||||
|
@ -151,6 +151,7 @@ interface SimpleProps {
|
||||
onCardMemberClick: OnCardMemberClick;
|
||||
onCardLabelClick: () => void;
|
||||
cardLabelVariant: CardLabelVariant;
|
||||
isPublic?: boolean;
|
||||
taskStatusFilter?: TaskStatusFilter;
|
||||
taskMetaFilters?: TaskMetaFilters;
|
||||
taskSorting?: TaskSorting;
|
||||
@ -188,6 +189,7 @@ const SimpleLists: React.FC<SimpleProps> = ({
|
||||
onExtraMenuOpen,
|
||||
onCardMemberClick,
|
||||
taskStatusFilter = initTaskStatusFilter,
|
||||
isPublic = false,
|
||||
taskMetaFilters = initTaskMetaFilters,
|
||||
taskSorting = initTaskSorting,
|
||||
}) => {
|
||||
@ -300,6 +302,7 @@ const SimpleLists: React.FC<SimpleProps> = ({
|
||||
onOpenComposer={id => setCurrentComposer(id)}
|
||||
isComposerOpen={currentComposer === taskGroup.id}
|
||||
onSaveName={name => onChangeTaskGroupName(taskGroup.id, name)}
|
||||
isPublic={isPublic}
|
||||
ref={columnDragProvided.innerRef}
|
||||
wrapperProps={columnDragProvided.draggableProps}
|
||||
headerProps={columnDragProvided.dragHandleProps}
|
||||
@ -328,6 +331,7 @@ const SimpleLists: React.FC<SimpleProps> = ({
|
||||
<Card
|
||||
toggleDirection={toggleDirection}
|
||||
toggleLabels={toggleLabels}
|
||||
isPublic={isPublic}
|
||||
labelVariant={cardLabelVariant}
|
||||
wrapperProps={{
|
||||
...taskProvided.draggableProps,
|
||||
@ -396,11 +400,13 @@ const SimpleLists: React.FC<SimpleProps> = ({
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
<AddList
|
||||
onSave={listName => {
|
||||
onCreateTaskGroup(listName);
|
||||
}}
|
||||
/>
|
||||
{!isPublic && (
|
||||
<AddList
|
||||
onSave={listName => {
|
||||
onCreateTaskGroup(listName);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</BoardWrapper>
|
||||
</BoardContainer>
|
||||
);
|
||||
|
@ -38,12 +38,17 @@ export const ListSeparator = styled.hr`
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
publicOn: null | string;
|
||||
onDeleteProject: () => void;
|
||||
onToggleProjectVisible: (visible: boolean) => void;
|
||||
};
|
||||
const ProjectSettings: React.FC<Props> = ({ onDeleteProject }) => {
|
||||
const ProjectSettings: React.FC<Props> = ({ publicOn, onDeleteProject, onToggleProjectVisible }) => {
|
||||
return (
|
||||
<>
|
||||
<ListActionsWrapper>
|
||||
<ListActionItemWrapper onClick={() => onToggleProjectVisible(publicOn === null)}>
|
||||
<ListActionItem>{`Make ${publicOn === null ? 'public' : 'private'}`}</ListActionItem>
|
||||
</ListActionItemWrapper>
|
||||
<ListActionItemWrapper onClick={() => onDeleteProject()}>
|
||||
<ListActionItem>Delete Project</ListActionItem>
|
||||
</ListActionItemWrapper>
|
||||
@ -127,5 +132,18 @@ const DeleteConfirm: React.FC<DeleteConfirmProps> = ({ description, deletedItems
|
||||
);
|
||||
};
|
||||
|
||||
export { DeleteConfirm };
|
||||
type PublicConfirmProps = {
|
||||
onConfirm: () => void;
|
||||
};
|
||||
|
||||
const PublicConfirm: React.FC<PublicConfirmProps> = ({ onConfirm }) => {
|
||||
return (
|
||||
<ConfirmWrapper>
|
||||
<ConfirmDescription>Public projects can be accessed by anyone with a link to the project.</ConfirmDescription>
|
||||
<ConfirmDeleteButton onClick={() => onConfirm()}>Make public</ConfirmDeleteButton>
|
||||
</ConfirmWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export { DeleteConfirm, PublicConfirm };
|
||||
export default ProjectSettings;
|
||||
|
@ -69,7 +69,7 @@ const CommentCreator: React.FC<CommentCreatorProps> = ({
|
||||
)}
|
||||
<CommentEditorContainer>
|
||||
<CommentTextArea
|
||||
showCommentActions={showCommentActions}
|
||||
$showCommentActions={showCommentActions}
|
||||
placeholder="Write a comment..."
|
||||
ref={$comment}
|
||||
disabled={disabled}
|
||||
|
@ -80,40 +80,44 @@ import {
|
||||
ActivityItemHeaderTitleName,
|
||||
ActivityItemComment,
|
||||
} from './Styles';
|
||||
import { useCurrentUser } from 'App/context';
|
||||
|
||||
type TaskDetailsProps = {};
|
||||
|
||||
const TaskDetailsLoading: React.FC<TaskDetailsProps> = () => {
|
||||
const { user } = useCurrentUser();
|
||||
return (
|
||||
<Container>
|
||||
<LeftSidebar>
|
||||
<LeftSidebarContent>
|
||||
<LeftSidebarSection>
|
||||
<SidebarTitle>TASK GROUP</SidebarTitle>
|
||||
<SidebarButton loading>
|
||||
<SidebarButton $loading>
|
||||
<SidebarSkeleton />
|
||||
</SidebarButton>
|
||||
<DueDateTitle>DUE DATE</DueDateTitle>
|
||||
<SidebarButton loading>
|
||||
<SidebarButton $loading>
|
||||
<SidebarSkeleton />
|
||||
</SidebarButton>
|
||||
</LeftSidebarSection>
|
||||
<AssignedUsersSection>
|
||||
<DueDateTitle>MEMBERS</DueDateTitle>
|
||||
<SidebarButton loading>
|
||||
<SidebarButton $loading>
|
||||
<SidebarSkeleton />
|
||||
</SidebarButton>
|
||||
</AssignedUsersSection>
|
||||
<ExtraActionsSection>
|
||||
<DueDateTitle>ACTIONS</DueDateTitle>
|
||||
<ActionButton disabled icon={<Tags width={12} height={12} />}>
|
||||
Labels
|
||||
</ActionButton>
|
||||
<ActionButton disabled icon={<CheckSquareOutline width={12} height={12} />}>
|
||||
Checklist
|
||||
</ActionButton>
|
||||
<ActionButton disabled>Cover</ActionButton>
|
||||
</ExtraActionsSection>
|
||||
{user && (
|
||||
<ExtraActionsSection>
|
||||
<DueDateTitle>ACTIONS</DueDateTitle>
|
||||
<ActionButton disabled icon={<Tags width={12} height={12} />}>
|
||||
Labels
|
||||
</ActionButton>
|
||||
<ActionButton disabled icon={<CheckSquareOutline width={12} height={12} />}>
|
||||
Checklist
|
||||
</ActionButton>
|
||||
<ActionButton disabled>Cover</ActionButton>
|
||||
</ExtraActionsSection>
|
||||
)}
|
||||
</LeftSidebarContent>
|
||||
</LeftSidebar>
|
||||
<ContentContainer>
|
||||
@ -125,23 +129,25 @@ const TaskDetailsLoading: React.FC<TaskDetailsProps> = () => {
|
||||
<span>Mark complete</span>
|
||||
</MarkCompleteButton>
|
||||
</HeaderLeft>
|
||||
<HeaderRight>
|
||||
<HeaderActionIcon>
|
||||
<Paperclip width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Clone width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Share width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Trash width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
</HeaderRight>
|
||||
{user && (
|
||||
<HeaderRight>
|
||||
<HeaderActionIcon>
|
||||
<Paperclip width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Clone width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Share width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Trash width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
</HeaderRight>
|
||||
)}
|
||||
</HeaderInnerContainer>
|
||||
<TaskDetailsTitleWrapper loading>
|
||||
<TaskDetailsTitle value="" disabled loading />
|
||||
<TaskDetailsTitleWrapper $loading>
|
||||
<TaskDetailsTitle value="" disabled $loading />
|
||||
</TaskDetailsTitleWrapper>
|
||||
</HeaderContainer>
|
||||
<InnerContentContainer>
|
||||
@ -151,9 +157,11 @@ const TaskDetailsLoading: React.FC<TaskDetailsProps> = () => {
|
||||
</TabBarSection>
|
||||
<ActivitySection />
|
||||
</InnerContentContainer>
|
||||
<CommentContainer>
|
||||
<CommentCreator disabled onCreateComment={() => null} onMemberProfile={() => null} />
|
||||
</CommentContainer>
|
||||
{user && (
|
||||
<CommentContainer>
|
||||
<CommentCreator disabled onCreateComment={() => null} onMemberProfile={() => null} />
|
||||
</CommentContainer>
|
||||
)}
|
||||
</ContentContainer>
|
||||
</Container>
|
||||
);
|
||||
|
@ -108,7 +108,7 @@ export const skeletonKeyframes = keyframes`
|
||||
}
|
||||
`;
|
||||
|
||||
export const SidebarButton = styled.div<{ loading?: boolean }>`
|
||||
export const SidebarButton = styled.div<{ $loading?: boolean }>`
|
||||
font-size: 14px;
|
||||
color: ${props => props.theme.colors.text.primary};
|
||||
min-height: 32px;
|
||||
@ -116,7 +116,7 @@ export const SidebarButton = styled.div<{ loading?: boolean }>`
|
||||
border-radius: 6px;
|
||||
|
||||
${props =>
|
||||
props.loading
|
||||
props.$loading
|
||||
? css`
|
||||
background: ${props.theme.colors.bg.primary};
|
||||
`
|
||||
@ -178,15 +178,15 @@ export const HeaderLeft = styled.div`
|
||||
justify-content: flex-start;
|
||||
`;
|
||||
|
||||
export const TaskDetailsTitleWrapper = styled.div<{ loading?: boolean }>`
|
||||
export const TaskDetailsTitleWrapper = styled.div<{ $loading?: boolean }>`
|
||||
width: 100%;
|
||||
margin: 8px 0 4px 0;
|
||||
display: flex;
|
||||
border-radius: 6px;
|
||||
${props => props.loading && `background: ${props.theme.colors.bg.primary};`}
|
||||
${props => props.$loading && `background: ${props.theme.colors.bg.primary};`}
|
||||
`;
|
||||
|
||||
export const TaskDetailsTitle = styled(TextareaAutosize)<{ loading?: boolean }>`
|
||||
export const TaskDetailsTitle = styled(TextareaAutosize)<{ $loading?: boolean }>`
|
||||
padding: 9px 8px 7px 8px;
|
||||
border-color: transparent;
|
||||
border-radius: 6px;
|
||||
@ -198,8 +198,11 @@ export const TaskDetailsTitle = styled(TextareaAutosize)<{ loading?: boolean }>`
|
||||
font-weight: 700;
|
||||
background: none;
|
||||
|
||||
&:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
${props =>
|
||||
props.loading
|
||||
props.$loading
|
||||
? css`
|
||||
background-image: linear-gradient(90deg, ${defaultBaseColor}, ${defaultHighlightColor}, ${defaultBaseColor});
|
||||
background-size: 200px 100%;
|
||||
@ -207,7 +210,7 @@ export const TaskDetailsTitle = styled(TextareaAutosize)<{ loading?: boolean }>`
|
||||
animation: ${skeletonKeyframes} 1.2s ease-in-out infinite;
|
||||
`
|
||||
: css`
|
||||
&:hover {
|
||||
&:not(:disabled):hover {
|
||||
border-color: #414561;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
@ -534,7 +537,7 @@ export const CommentProfile = styled(TaskAssignee)`
|
||||
align-items: normal;
|
||||
`;
|
||||
|
||||
export const CommentTextArea = styled(TextareaAutosize)<{ showCommentActions: boolean }>`
|
||||
export const CommentTextArea = styled(TextareaAutosize)<{ $showCommentActions: boolean }>`
|
||||
width: 100%;
|
||||
line-height: 28px;
|
||||
padding: 4px 6px;
|
||||
@ -546,7 +549,7 @@ export const CommentTextArea = styled(TextareaAutosize)<{ showCommentActions: bo
|
||||
min-height: 36px;
|
||||
max-height: 36px;
|
||||
${props =>
|
||||
props.showCommentActions
|
||||
props.$showCommentActions
|
||||
? css`
|
||||
min-height: 80px;
|
||||
max-height: none;
|
||||
|
@ -83,6 +83,7 @@ import Checklist, { ChecklistItem, ChecklistItems } from '../Checklist';
|
||||
import onDragEnd from './onDragEnd';
|
||||
import { plugin as em } from './remark';
|
||||
import ActivityMessage from './ActivityMessage';
|
||||
import { useCurrentUser } from 'App/context';
|
||||
|
||||
const parseEmojis = (value: string) => {
|
||||
const emojisArray = toArray(value);
|
||||
@ -277,6 +278,7 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
onToggleChecklistItem,
|
||||
onMemberProfile,
|
||||
}) => {
|
||||
const { user } = useCurrentUser();
|
||||
const [taskName, setTaskName] = useState(task.name);
|
||||
const [editTaskDescription, setEditTaskDescription] = useState(() => {
|
||||
if (task.description) {
|
||||
@ -338,7 +340,9 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
<SidebarButton
|
||||
ref={$dueDateBtn}
|
||||
onClick={() => {
|
||||
onOpenDueDatePopop(task, $dueDateBtn);
|
||||
if (user) {
|
||||
onOpenDueDatePopop(task, $dueDateBtn);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{task.dueDate ? (
|
||||
@ -360,14 +364,18 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
member={m}
|
||||
size={32}
|
||||
onMemberProfile={$target => {
|
||||
onMemberProfile($target, m.id);
|
||||
if (user) {
|
||||
onMemberProfile($target, m.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<AssignUserIcon
|
||||
ref={$addMemberBtn}
|
||||
onClick={() => {
|
||||
onOpenAddMemberPopup(task, $addMemberBtn);
|
||||
if (user) {
|
||||
onOpenAddMemberPopup(task, $addMemberBtn);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Plus width={16} height={16} />
|
||||
@ -377,7 +385,9 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
<AssignUsersButton
|
||||
ref={$noMemberBtn}
|
||||
onClick={() => {
|
||||
onOpenAddMemberPopup(task, $noMemberBtn);
|
||||
if (user) {
|
||||
onOpenAddMemberPopup(task, $noMemberBtn);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AssignUserIcon>
|
||||
@ -387,26 +397,28 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
</AssignUsersButton>
|
||||
)}
|
||||
</AssignedUsersSection>
|
||||
<ExtraActionsSection>
|
||||
<DueDateTitle>ACTIONS</DueDateTitle>
|
||||
<ActionButton
|
||||
onClick={$target => {
|
||||
onOpenAddLabelPopup(task, $target);
|
||||
}}
|
||||
icon={<Tags width={12} height={12} />}
|
||||
>
|
||||
Labels
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
onClick={$target => {
|
||||
onOpenAddChecklistPopup(task, $target);
|
||||
}}
|
||||
icon={<CheckSquareOutline width={12} height={12} />}
|
||||
>
|
||||
Checklist
|
||||
</ActionButton>
|
||||
<ActionButton>Cover</ActionButton>
|
||||
</ExtraActionsSection>
|
||||
{user && (
|
||||
<ExtraActionsSection>
|
||||
<DueDateTitle>ACTIONS</DueDateTitle>
|
||||
<ActionButton
|
||||
onClick={$target => {
|
||||
onOpenAddLabelPopup(task, $target);
|
||||
}}
|
||||
icon={<Tags width={12} height={12} />}
|
||||
>
|
||||
Labels
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
onClick={$target => {
|
||||
onOpenAddChecklistPopup(task, $target);
|
||||
}}
|
||||
icon={<CheckSquareOutline width={12} height={12} />}
|
||||
>
|
||||
Checklist
|
||||
</ActionButton>
|
||||
<ActionButton>Cover</ActionButton>
|
||||
</ExtraActionsSection>
|
||||
)}
|
||||
</LeftSidebarContent>
|
||||
</LeftSidebar>
|
||||
<ContentContainer>
|
||||
@ -414,34 +426,40 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
<HeaderInnerContainer>
|
||||
<HeaderLeft>
|
||||
<MarkCompleteButton
|
||||
disabled={user === null}
|
||||
invert={task.complete ?? false}
|
||||
onClick={() => {
|
||||
onToggleTaskComplete(task);
|
||||
if (user) {
|
||||
onToggleTaskComplete(task);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Checkmark width={8} height={8} />
|
||||
<span>{task.complete ? 'Completed' : 'Mark complete'}</span>
|
||||
</MarkCompleteButton>
|
||||
</HeaderLeft>
|
||||
<HeaderRight>
|
||||
<HeaderActionIcon>
|
||||
<Paperclip width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Clone width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Share width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon onClick={() => onDeleteTask(task)}>
|
||||
<Trash width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
</HeaderRight>
|
||||
{user && (
|
||||
<HeaderRight>
|
||||
<HeaderActionIcon>
|
||||
<Paperclip width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Clone width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon>
|
||||
<Share width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
<HeaderActionIcon onClick={() => onDeleteTask(task)}>
|
||||
<Trash width={16} height={16} />
|
||||
</HeaderActionIcon>
|
||||
</HeaderRight>
|
||||
)}
|
||||
</HeaderInnerContainer>
|
||||
<TaskDetailsTitleWrapper>
|
||||
<TaskDetailsTitle
|
||||
value={taskName}
|
||||
ref={$detailsTitle}
|
||||
disabled={user === null}
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
@ -496,7 +514,7 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
<Editor
|
||||
defaultValue={task.description ?? ''}
|
||||
theme={dark}
|
||||
readOnly={!editTaskDescription}
|
||||
readOnly={user === null || !editTaskDescription}
|
||||
autoFocus
|
||||
onChange={value => {
|
||||
setSaveTimeout(() => {
|
||||
@ -612,15 +630,15 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
)}
|
||||
</ActivitySection>
|
||||
</InnerContentContainer>
|
||||
<CommentContainer>
|
||||
{me && (
|
||||
{me && (
|
||||
<CommentContainer>
|
||||
<CommentCreator
|
||||
me={me}
|
||||
onCreateComment={message => onCreateComment(task, message)}
|
||||
onMemberProfile={onMemberProfile}
|
||||
/>
|
||||
)}
|
||||
</CommentContainer>
|
||||
</CommentContainer>
|
||||
)}
|
||||
</ContentContainer>
|
||||
</Container>
|
||||
);
|
||||
|
63
frontend/src/shared/components/TopNavbar/LoggedOut.tsx
Normal file
63
frontend/src/shared/components/TopNavbar/LoggedOut.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import { Home, Star, Bell, AngleDown, BarChart, CheckCircle, ListUnordered } from 'shared/icons';
|
||||
import { RoleCode } from 'shared/generated/graphql';
|
||||
import * as S from './Styles';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export type MenuItem = {
|
||||
name: string;
|
||||
link: string;
|
||||
};
|
||||
|
||||
type NavBarProps = {
|
||||
menuType?: Array<MenuItem> | null;
|
||||
name: string | null;
|
||||
};
|
||||
|
||||
const NavBar: React.FC<NavBarProps> = ({ menuType, name }) => {
|
||||
return (
|
||||
<S.NavbarWrapper>
|
||||
<S.NavbarHeader>
|
||||
<S.ProjectActions>
|
||||
<S.ProjectSwitch>
|
||||
<S.ProjectSwitchInner>
|
||||
<S.TaskcafeLogo innerColor="#9f46e4" outerColor="#000" width={32} height={32} />
|
||||
</S.ProjectSwitchInner>
|
||||
</S.ProjectSwitch>
|
||||
<S.ProjectInfo>
|
||||
<S.ProjectMeta>{name && <S.ProjectName>{name}</S.ProjectName>}</S.ProjectMeta>
|
||||
{name && (
|
||||
<S.ProjectTabs>
|
||||
{menuType &&
|
||||
menuType.map((menu, idx) => {
|
||||
return (
|
||||
<S.ProjectTab
|
||||
key={menu.name}
|
||||
to={menu.link}
|
||||
exact
|
||||
onClick={() => {
|
||||
// TODO
|
||||
}}
|
||||
>
|
||||
{menu.name}
|
||||
</S.ProjectTab>
|
||||
);
|
||||
})}
|
||||
</S.ProjectTabs>
|
||||
)}
|
||||
</S.ProjectInfo>
|
||||
</S.ProjectActions>
|
||||
<S.LogoContainer to="/">
|
||||
<S.TaskcafeTitle>Taskcafé</S.TaskcafeTitle>
|
||||
</S.LogoContainer>
|
||||
<S.GlobalActions>
|
||||
<Link to="/login">
|
||||
<S.SignIn>Sign In</S.SignIn>
|
||||
</Link>
|
||||
</S.GlobalActions>
|
||||
</S.NavbarHeader>
|
||||
</S.NavbarWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavBar;
|
@ -297,6 +297,16 @@ export const ProjectFinder = styled(Button)`
|
||||
padding: 6px 12px;
|
||||
`;
|
||||
|
||||
export const SignUp = styled(Button)`
|
||||
margin-right: 8px;
|
||||
padding: 6px 12px;
|
||||
`;
|
||||
|
||||
export const SignIn = styled(Button)`
|
||||
margin-right: 20px;
|
||||
padding: 6px 12px;
|
||||
`;
|
||||
|
||||
export const NavSeparator = styled.div`
|
||||
width: 1px;
|
||||
background: ${props => props.theme.colors.border};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@ const FIND_PROJECT_QUERY = gql`
|
||||
query findProject($projectID: UUID!) {
|
||||
findProject(input: { projectID: $projectID }) {
|
||||
name
|
||||
publicOn
|
||||
team {
|
||||
id
|
||||
}
|
||||
|
14
frontend/src/shared/graphql/toggleProjectVisibility.ts
Normal file
14
frontend/src/shared/graphql/toggleProjectVisibility.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
export const DELETE_PROJECT_MUTATION = gql`
|
||||
mutation toggleProjectVisibility($projectID: UUID!, $isPublic: Boolean!) {
|
||||
toggleProjectVisibility(input: { projectID: $projectID, isPublic: $isPublic }) {
|
||||
project {
|
||||
id
|
||||
publicOn
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default DELETE_PROJECT_MUTATION;
|
@ -39,11 +39,6 @@
|
||||
ts-invariant "^0.4.4"
|
||||
tslib "^1.10.0"
|
||||
|
||||
"@ardatan/aggregate-error@0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.1.tgz#1403ac5de10d8ca689fc1f65844c27179ae1d44f"
|
||||
integrity sha512-UQ9BequOTIavs0pTHLMwQwKQF8tTV1oezY/H2O9chA+JNPFZSua55xpU5dPSjAU9/jLJ1VwU+HJuTVN8u7S6Fg==
|
||||
|
||||
"@ardatan/aggregate-error@0.0.6":
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609"
|
||||
@ -1349,13 +1344,13 @@
|
||||
ts-node "^9"
|
||||
tslib "^2"
|
||||
|
||||
"@graphql-codegen/cli@^1.13.2":
|
||||
version "1.19.4"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-1.19.4.tgz#16e5caaa46ee159cbb01e2a2699203f8f25faac2"
|
||||
integrity sha512-PN1xgaXZaTTEPhBfQkIRK82RzrzY8Pr+tfCqOtibeJMed0mtIJ5gSQfollRbtZ0/t7ZEmYCxojqQiVSbKzXDMw==
|
||||
"@graphql-codegen/cli@^1.21.4":
|
||||
version "1.21.4"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-1.21.4.tgz#41ce6abc6b33e369a3ee795621373b8ffa1aadeb"
|
||||
integrity sha512-fCrPn7DeGnCU6d9xjo04VSzIGioVLj1BAjuZpgRJNNjyzTmv+qZJJVTWfD55J17XxlhFsfKJBprtdmRxZ3V2hw==
|
||||
dependencies:
|
||||
"@graphql-codegen/core" "1.17.9"
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.2"
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.5"
|
||||
"@graphql-tools/apollo-engine-loader" "^6"
|
||||
"@graphql-tools/code-file-loader" "^6"
|
||||
"@graphql-tools/git-loader" "^6"
|
||||
@ -1365,16 +1360,15 @@
|
||||
"@graphql-tools/load" "^6"
|
||||
"@graphql-tools/prisma-loader" "^6"
|
||||
"@graphql-tools/url-loader" "^6"
|
||||
"@graphql-tools/utils" "^6"
|
||||
"@graphql-tools/utils" "^7.0.0"
|
||||
ansi-escapes "^4.3.1"
|
||||
camel-case "^4.1.1"
|
||||
chalk "^4.1.0"
|
||||
change-case-all "1.0.14"
|
||||
chokidar "^3.4.3"
|
||||
common-tags "^1.8.0"
|
||||
constant-case "^3.0.3"
|
||||
cosmiconfig "^7.0.0"
|
||||
debounce "^1.2.0"
|
||||
dependency-graph "^0.9.0"
|
||||
dependency-graph "^0.11.0"
|
||||
detect-indent "^6.0.0"
|
||||
glob "^7.1.6"
|
||||
graphql-config "^3.2.0"
|
||||
@ -1386,17 +1380,14 @@
|
||||
listr "^0.14.3"
|
||||
listr-update-renderer "^0.5.0"
|
||||
log-symbols "^4.0.0"
|
||||
lower-case "^2.0.1"
|
||||
minimatch "^3.0.4"
|
||||
mkdirp "^1.0.4"
|
||||
pascal-case "^3.1.1"
|
||||
request "^2.88.2"
|
||||
string-env-interpolation "^1.0.1"
|
||||
ts-log "^2.2.3"
|
||||
tslib "~2.0.1"
|
||||
upper-case "^2.0.1"
|
||||
tslib "~2.2.0"
|
||||
valid-url "^1.0.9"
|
||||
wrap-ansi "^7.0.0"
|
||||
yaml "^1.10.0"
|
||||
yargs "^16.1.1"
|
||||
|
||||
"@graphql-codegen/core@1.17.9":
|
||||
@ -1409,23 +1400,6 @@
|
||||
"@graphql-tools/utils" "^6"
|
||||
tslib "~2.0.1"
|
||||
|
||||
"@graphql-codegen/plugin-helpers@1.17.7":
|
||||
version "1.17.7"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.17.7.tgz#5903105fda9470aafefe9da29e3a6fb3a52b8376"
|
||||
integrity sha512-LsXS0s/ZOACZXa3W29ekcaQLzP8TsYzow6nIjW6rtkWX5T0EDooBQbDn1cdLdlpenqbUU+vtONwR6Qqc6hrq2Q==
|
||||
dependencies:
|
||||
"@graphql-tools/utils" "^6.0.0"
|
||||
camel-case "4.1.1"
|
||||
common-tags "1.8.0"
|
||||
constant-case "3.0.3"
|
||||
import-from "3.0.0"
|
||||
lodash "~4.17.15"
|
||||
lower-case "2.0.1"
|
||||
param-case "3.0.3"
|
||||
pascal-case "3.1.1"
|
||||
tslib "~2.0.0"
|
||||
upper-case "2.0.1"
|
||||
|
||||
"@graphql-codegen/plugin-helpers@^1.18.2":
|
||||
version "1.18.2"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.2.tgz#57011076cb8b8f5d04d37d226a5eda300c01be94"
|
||||
@ -1443,69 +1417,64 @@
|
||||
tslib "~2.0.1"
|
||||
upper-case "2.0.1"
|
||||
|
||||
"@graphql-codegen/typescript-operations@^1.13.2":
|
||||
version "1.17.12"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-1.17.12.tgz#25e0f0ede1bcd165196f0c161286d745395c7768"
|
||||
integrity sha512-UXe/O3kNAlLptURuripAhK8n/Gf6FthL7xr6sG4vpuLVwrWjXu/KlS7+TP+UvlI9OH2LICm0KHqA0xoFCjNbMg==
|
||||
"@graphql-codegen/plugin-helpers@^1.18.5":
|
||||
version "1.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.5.tgz#e1d875cfb6a2f7bf4b4318135f7fee6e1200f3b0"
|
||||
integrity sha512-xY8dWdU4+mm+253esLYcKQIgWZEgI3spKPmMRQ+oAxlrCn9oIcdhhiMqNxa9rHS20xpZtlAjozxHulrqjFLuyA==
|
||||
dependencies:
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.2"
|
||||
"@graphql-codegen/typescript" "^1.18.1"
|
||||
"@graphql-codegen/visitor-plugin-common" "^1.17.20"
|
||||
auto-bind "~4.0.0"
|
||||
tslib "~2.0.1"
|
||||
"@graphql-tools/utils" "^7.0.0"
|
||||
common-tags "1.8.0"
|
||||
import-from "3.0.0"
|
||||
lodash "~4.17.20"
|
||||
tslib "~2.2.0"
|
||||
|
||||
"@graphql-codegen/typescript-react-apollo@^1.13.2":
|
||||
version "1.17.7"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-react-apollo/-/typescript-react-apollo-1.17.7.tgz#b1d1ad1150c07097566f46c208ca54d42a8ad4f5"
|
||||
integrity sha512-Yoc7XwruETJ1Aoi5UBLF+AVsyReGPxI9jEpsNWv/Xm5zzGGk8iVwKIwos9hBjzkDO0sQooZZa0UXBKXNQa7j0w==
|
||||
"@graphql-codegen/typescript-operations@^1.17.16":
|
||||
version "1.17.16"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-1.17.16.tgz#75eb389f268b2dbd2e46b235bcb957be561c31cb"
|
||||
integrity sha512-DoWIhg/c2XS4IpgRLRXRBJDwmKoIl6KuzL2iO9GElX0rdjYguwbqx6iDV1pgktTTajMy8pXP56oZhmEcZLRD2Q==
|
||||
dependencies:
|
||||
"@graphql-codegen/plugin-helpers" "1.17.7"
|
||||
"@graphql-codegen/visitor-plugin-common" "1.17.7"
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.5"
|
||||
"@graphql-codegen/typescript" "^1.22.0"
|
||||
"@graphql-codegen/visitor-plugin-common" "^1.20.0"
|
||||
auto-bind "~4.0.0"
|
||||
camel-case "4.1.1"
|
||||
pascal-case "3.1.1"
|
||||
tslib "~2.0.0"
|
||||
tslib "~2.2.0"
|
||||
|
||||
"@graphql-codegen/typescript@^1.13.2", "@graphql-codegen/typescript@^1.18.1":
|
||||
version "1.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.19.0.tgz#05b1b4502b91dee53ec4f0ae39e9537eff004c5c"
|
||||
integrity sha512-ThpMdtb6LmEKzLNxlotpk33eIMfX1i1aAlYDaqctIhFjZ2Rbvkgdb8q/5/my7yeH33BLnuqHDKrdkDsAAvCHcw==
|
||||
"@graphql-codegen/typescript-react-apollo@^2.2.4":
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-react-apollo/-/typescript-react-apollo-2.2.4.tgz#149b8e4f2b684295a2e6be8b9e88285a0f8be0f6"
|
||||
integrity sha512-2db+KrujuBjQ8GraamEPGEp74Bxcw6Vd2AubhqenoTmHjK/Jw3HLpO8ndetcoND08e3EZCb/CNyKkLcxwYD0eg==
|
||||
dependencies:
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.2"
|
||||
"@graphql-codegen/visitor-plugin-common" "^1.17.21"
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.5"
|
||||
"@graphql-codegen/visitor-plugin-common" "^1.20.0"
|
||||
auto-bind "~4.0.0"
|
||||
tslib "~2.0.1"
|
||||
change-case-all "1.0.14"
|
||||
tslib "~2.2.0"
|
||||
|
||||
"@graphql-codegen/visitor-plugin-common@1.17.7":
|
||||
version "1.17.7"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.17.7.tgz#3158ca4fc7d45a0f5a6ad0706061015eae481d9e"
|
||||
integrity sha512-z5WvYqgCgPAAuMJMOE0e0nEicdaQRm59/vP+yYihKQmwrASzPlqa1BUiGDnfrPcCooB9fEUHB+cQb3gt9GRfEg==
|
||||
"@graphql-codegen/typescript@^1.22.0":
|
||||
version "1.22.0"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.22.0.tgz#d05be3a971e5d75a076a43e123b6330f4366a6ab"
|
||||
integrity sha512-YzN/3MBYHrP110m8JgUWQIHt7Ivi3JXiq0RT5XNx/F9mVOSbZz6Ezbaji8YJA3y04Gl2f6ZgtdGazWANUvcOcg==
|
||||
dependencies:
|
||||
"@graphql-codegen/plugin-helpers" "1.17.7"
|
||||
"@graphql-tools/relay-operation-optimizer" "6.0.15"
|
||||
array.prototype.flatmap "1.2.3"
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.5"
|
||||
"@graphql-codegen/visitor-plugin-common" "^1.20.0"
|
||||
auto-bind "~4.0.0"
|
||||
dependency-graph "0.9.0"
|
||||
graphql-tag "2.11.0"
|
||||
parse-filepath "1.0.2"
|
||||
pascal-case "3.1.1"
|
||||
tslib "~2.0.0"
|
||||
tslib "~2.2.0"
|
||||
|
||||
"@graphql-codegen/visitor-plugin-common@^1.17.20", "@graphql-codegen/visitor-plugin-common@^1.17.21":
|
||||
version "1.17.21"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.17.21.tgz#e47a5623392bcdb89d5af2484798a2fd9a59df8c"
|
||||
integrity sha512-rhdJdj+4DAMgMSBlgkvfOMw65L46sAtYb7G/n9ucc9uJGUbiIcgvS/wpoQ/gxz2eUaNfcoFmjVLm+dkTM/XwqA==
|
||||
"@graphql-codegen/visitor-plugin-common@^1.20.0":
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.20.0.tgz#38d829eab7370c79aa5229190788f94adcae8f76"
|
||||
integrity sha512-AYrpy8NA3DpvhDLqYGerQRv44S+YAMPKtwT8x9GNVjzP0gVfmqi3gG1bDWbP5sm6kOZKvDC0kTxGePuBSZerxw==
|
||||
dependencies:
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.2"
|
||||
"@graphql-codegen/plugin-helpers" "^1.18.5"
|
||||
"@graphql-tools/optimize" "^1.0.1"
|
||||
"@graphql-tools/relay-operation-optimizer" "^6"
|
||||
array.prototype.flatmap "^1.2.4"
|
||||
auto-bind "~4.0.0"
|
||||
dependency-graph "^0.9.0"
|
||||
change-case-all "1.0.14"
|
||||
dependency-graph "^0.11.0"
|
||||
graphql-tag "^2.11.0"
|
||||
parse-filepath "^1.0.2"
|
||||
pascal-case "^3.1.1"
|
||||
tslib "~2.0.1"
|
||||
tslib "~2.2.0"
|
||||
|
||||
"@graphql-tools/apollo-engine-loader@^6":
|
||||
version "6.2.5"
|
||||
@ -1665,14 +1634,6 @@
|
||||
tslib "~2.0.1"
|
||||
yaml-ast-parser "^0.0.43"
|
||||
|
||||
"@graphql-tools/relay-operation-optimizer@6.0.15":
|
||||
version "6.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.0.15.tgz#f991499c54945cb8fa2396bb5292252fbda0a773"
|
||||
integrity sha512-Y4h2kclKh5HvyvmoxeZiDhqdhMKfLKamOYx6UVpFsbeKb6Tt9RCNPVhpa+YToXxUXl0PvjhxZWeQ4lZY0GE0ug==
|
||||
dependencies:
|
||||
"@graphql-tools/utils" "6.0.15"
|
||||
relay-compiler "10.0.0"
|
||||
|
||||
"@graphql-tools/relay-operation-optimizer@^6":
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.3.0.tgz#f8c7f6c8aa4a9cf50ab151fbc5db4f4282a79532"
|
||||
@ -1713,14 +1674,6 @@
|
||||
valid-url "1.0.9"
|
||||
ws "7.4.1"
|
||||
|
||||
"@graphql-tools/utils@6.0.15":
|
||||
version "6.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-6.0.15.tgz#6d54d383285bea3c22797531933b62a408e78e49"
|
||||
integrity sha512-VG5cMLPgh9RDLGHamGpXVnBrNw7bZGT46LrxK7IIqDZI9H0GPsRCo8+p+CfDkw0IlDiEECb624WVCpm9IYNecA==
|
||||
dependencies:
|
||||
"@ardatan/aggregate-error" "0.0.1"
|
||||
camel-case "4.1.1"
|
||||
|
||||
"@graphql-tools/utils@^6", "@graphql-tools/utils@^6.0.0":
|
||||
version "6.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-6.2.4.tgz#38a2314d2e5e229ad4f78cca44e1199e18d55856"
|
||||
@ -2413,10 +2366,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
||||
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
|
||||
|
||||
"@types/styled-components@^5.0.0":
|
||||
version "5.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.7.tgz#3cd10b088c1cb1acde2e4b166b3e8275a3083710"
|
||||
integrity sha512-BJzPhFygYspyefAGFZTZ/8lCEY4Tk+Iqktvnko3xmJf9LrLqs3+grxPeU3O0zLl6yjbYBopD0/VikbHgXDbJtA==
|
||||
"@types/styled-components@^5.1.0":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.9.tgz#00d3d84b501420521c4db727e3c195459f87a6cf"
|
||||
integrity sha512-kbEG6YlwK8rucITpKEr6pA4Ho9KSQHUUOzZ9lY3va1mtcjvS3D0wDciFyHEiNHKLL/npZCKDQJqm0x44sPO9oA==
|
||||
dependencies:
|
||||
"@types/hoist-non-react-statics" "*"
|
||||
"@types/react" "*"
|
||||
@ -3076,15 +3029,6 @@ array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.0-next.1"
|
||||
|
||||
array.prototype.flatmap@1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz#1c13f84a178566042dd63de4414440db9222e443"
|
||||
integrity sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.0-next.1"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
array.prototype.flatmap@^1.2.3, array.prototype.flatmap@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9"
|
||||
@ -3881,7 +3825,7 @@ camel-case@4.1.1:
|
||||
pascal-case "^3.1.1"
|
||||
tslib "^1.10.0"
|
||||
|
||||
camel-case@4.1.2, camel-case@^4.1.1:
|
||||
camel-case@4.1.2, camel-case@^4.1.1, camel-case@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
|
||||
integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
|
||||
@ -3919,6 +3863,15 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, can
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001168.tgz#6fcd098c139d003b9bd484cbb9ca26cb89907f9a"
|
||||
integrity sha512-P2zmX7swIXKu+GMMR01TWa4csIKELTNnZKc+f1CjebmZJQtTAEXmpQSoKVJVVcvPGAA0TEYTOUp3VehavZSFPQ==
|
||||
|
||||
capital-case@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669"
|
||||
integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==
|
||||
dependencies:
|
||||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
upper-case-first "^2.0.2"
|
||||
|
||||
capture-exit@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4"
|
||||
@ -3964,6 +3917,40 @@ chalk@^4.0.0, chalk@^4.1.0:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
change-case-all@1.0.14:
|
||||
version "1.0.14"
|
||||
resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.14.tgz#bac04da08ad143278d0ac3dda7eccd39280bfba1"
|
||||
integrity sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==
|
||||
dependencies:
|
||||
change-case "^4.1.2"
|
||||
is-lower-case "^2.0.2"
|
||||
is-upper-case "^2.0.2"
|
||||
lower-case "^2.0.2"
|
||||
lower-case-first "^2.0.2"
|
||||
sponge-case "^1.0.1"
|
||||
swap-case "^2.0.2"
|
||||
title-case "^3.0.3"
|
||||
upper-case "^2.0.2"
|
||||
upper-case-first "^2.0.2"
|
||||
|
||||
change-case@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12"
|
||||
integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==
|
||||
dependencies:
|
||||
camel-case "^4.1.2"
|
||||
capital-case "^1.0.4"
|
||||
constant-case "^3.0.4"
|
||||
dot-case "^3.0.4"
|
||||
header-case "^2.0.4"
|
||||
no-case "^3.0.4"
|
||||
param-case "^3.0.4"
|
||||
pascal-case "^3.1.2"
|
||||
path-case "^3.0.4"
|
||||
sentence-case "^3.0.4"
|
||||
snake-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
character-entities-legacy@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
|
||||
@ -4369,7 +4356,7 @@ constant-case@3.0.3:
|
||||
tslib "^1.10.0"
|
||||
upper-case "^2.0.1"
|
||||
|
||||
constant-case@^3.0.3:
|
||||
constant-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1"
|
||||
integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==
|
||||
@ -4459,7 +4446,7 @@ core-js-pure@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.8.1.tgz#23f84048f366fdfcf52d3fd1c68fec349177d119"
|
||||
integrity sha512-Se+LaxqXlVXGvmexKGPvnUIYC1jwXu1H6Pkyb3uBM5d8/NELMYCHs/4/roD7721NxrTLyv7e5nXd5/QLBO+10g==
|
||||
|
||||
core-js@^2.4.0, core-js@^2.4.1:
|
||||
core-js@^2.4.0:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||
@ -5042,10 +5029,10 @@ depd@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
|
||||
|
||||
dependency-graph@0.9.0, dependency-graph@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.9.0.tgz#11aed7e203bc8b00f48356d92db27b265c445318"
|
||||
integrity sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==
|
||||
dependency-graph@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27"
|
||||
integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==
|
||||
|
||||
des.js@^1.0.0:
|
||||
version "1.0.1"
|
||||
@ -5407,13 +5394,6 @@ encodeurl@~1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
|
||||
integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
|
||||
dependencies:
|
||||
iconv-lite "^0.6.2"
|
||||
|
||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
@ -6117,20 +6097,6 @@ fbjs-css-vars@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
|
||||
integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
|
||||
|
||||
fbjs@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a"
|
||||
integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==
|
||||
dependencies:
|
||||
core-js "^2.4.1"
|
||||
fbjs-css-vars "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.18"
|
||||
|
||||
fbjs@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165"
|
||||
@ -6711,7 +6677,7 @@ graphql-request@^3.3.0:
|
||||
extract-files "^9.0.0"
|
||||
form-data "^3.0.0"
|
||||
|
||||
graphql-tag@2.11.0, graphql-tag@^2.10.3, graphql-tag@^2.11.0:
|
||||
graphql-tag@^2.10.3, graphql-tag@^2.11.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd"
|
||||
integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA==
|
||||
@ -6876,6 +6842,14 @@ he@^1.1.0, he@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
header-case@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063"
|
||||
integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==
|
||||
dependencies:
|
||||
capital-case "^1.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
hex-color-regex@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
||||
@ -7128,13 +7102,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
|
||||
integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
icss-utils@^4.0.0, icss-utils@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467"
|
||||
@ -7591,6 +7558,13 @@ is-hexadecimal@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
|
||||
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
|
||||
|
||||
is-lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-2.0.2.tgz#1c0884d3012c841556243483aa5d522f47396d2a"
|
||||
integrity sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
is-negative-zero@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
|
||||
@ -7695,7 +7669,7 @@ is-root@2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c"
|
||||
integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==
|
||||
|
||||
is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
@ -7731,6 +7705,13 @@ is-unc-path@^1.0.0:
|
||||
dependencies:
|
||||
unc-path-regex "^0.1.2"
|
||||
|
||||
is-upper-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649"
|
||||
integrity sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
is-whitespace-character@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"
|
||||
@ -7790,14 +7771,6 @@ isobject@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
|
||||
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
isomorphic-fetch@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4"
|
||||
@ -8841,7 +8814,7 @@ lodash.uniq@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@~4.17.15, lodash@~4.17.20:
|
||||
"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@~4.17.20:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
@ -8881,6 +8854,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
lower-case-first@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-2.0.2.tgz#64c2324a2250bf7c37c5901e76a5b5309301160b"
|
||||
integrity sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
lower-case@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7"
|
||||
@ -8888,7 +8868,7 @@ lower-case@2.0.1:
|
||||
dependencies:
|
||||
tslib "^1.10.0"
|
||||
|
||||
lower-case@^2.0.1, lower-case@^2.0.2:
|
||||
lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
|
||||
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
|
||||
@ -9397,14 +9377,6 @@ node-fetch@2.6.1, node-fetch@^2.6.1:
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||
@ -9919,7 +9891,7 @@ param-case@3.0.3:
|
||||
dot-case "^3.0.3"
|
||||
tslib "^1.10.0"
|
||||
|
||||
param-case@^3.0.3:
|
||||
param-case@^3.0.3, param-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
|
||||
integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
|
||||
@ -9969,7 +9941,7 @@ parse-entities@^2.0.0:
|
||||
is-decimal "^1.0.0"
|
||||
is-hexadecimal "^1.0.0"
|
||||
|
||||
parse-filepath@1.0.2, parse-filepath@^1.0.2:
|
||||
parse-filepath@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
|
||||
integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=
|
||||
@ -10044,6 +10016,14 @@ path-browserify@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
|
||||
integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
|
||||
|
||||
path-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f"
|
||||
integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==
|
||||
dependencies:
|
||||
dot-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
path-dirname@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
|
||||
@ -11844,28 +11824,6 @@ relateurl@^0.2.7:
|
||||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
||||
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
|
||||
|
||||
relay-compiler@10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/relay-compiler/-/relay-compiler-10.0.0.tgz#04d50d8ec53e3f683bc379b756cf0542a76105af"
|
||||
integrity sha512-EVBMcMCiP+waOPR2930cNCCsac1sNhfQayzS+bOEMz2Lls5Bx7grhaadkBZLTEdCHQ1kf7lrsmcMDqj9mxABFw==
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/generator" "^7.5.0"
|
||||
"@babel/parser" "^7.0.0"
|
||||
"@babel/runtime" "^7.0.0"
|
||||
"@babel/traverse" "^7.0.0"
|
||||
"@babel/types" "^7.0.0"
|
||||
babel-preset-fbjs "^3.3.0"
|
||||
chalk "^4.0.0"
|
||||
fb-watchman "^2.0.0"
|
||||
fbjs "^1.0.0"
|
||||
glob "^7.1.1"
|
||||
immutable "~3.7.6"
|
||||
nullthrows "^1.1.1"
|
||||
relay-runtime "10.0.0"
|
||||
signedsource "^1.0.0"
|
||||
yargs "^15.3.1"
|
||||
|
||||
relay-compiler@10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/relay-compiler/-/relay-compiler-10.1.0.tgz#fb4672cdbe9b54869a3a79759edd8c2d91609cbe"
|
||||
@ -11888,14 +11846,6 @@ relay-compiler@10.1.0:
|
||||
signedsource "^1.0.0"
|
||||
yargs "^15.3.1"
|
||||
|
||||
relay-runtime@10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-10.0.0.tgz#cfceb0f8453b39a385d63093f2dbf1702ddc02b3"
|
||||
integrity sha512-QEpFwEjvGgWgQ0MPJyrZKggaCoGMKwxPQx7NwYl4FcMmxZcicc8wk6vI1iTxl0tsPKgW/YG8FgueQR+X7ZtZqw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
fbjs "^1.0.0"
|
||||
|
||||
relay-runtime@10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-10.1.0.tgz#4753bf36e95e8d862cef33608e3d98b4ed730d16"
|
||||
@ -11987,7 +11937,7 @@ request-promise-native@^1.0.5:
|
||||
stealthy-require "^1.1.1"
|
||||
tough-cookie "^2.3.3"
|
||||
|
||||
request@^2.87.0, request@^2.88.0, request@^2.88.2:
|
||||
request@^2.87.0, request@^2.88.0:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||
@ -12267,7 +12217,7 @@ safe-regex@^1.1.0:
|
||||
dependencies:
|
||||
ret "~0.1.10"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
@ -12411,6 +12361,15 @@ send@0.17.1:
|
||||
range-parser "~1.2.1"
|
||||
statuses "~1.5.0"
|
||||
|
||||
sentence-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f"
|
||||
integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==
|
||||
dependencies:
|
||||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
upper-case-first "^2.0.2"
|
||||
|
||||
serialize-javascript@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
|
||||
@ -12616,6 +12575,14 @@ smooth-scroll-into-view-if-needed@^1.1.27:
|
||||
dependencies:
|
||||
scroll-into-view-if-needed "^2.2.26"
|
||||
|
||||
snake-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c"
|
||||
integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==
|
||||
dependencies:
|
||||
dot-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
@ -12778,6 +12745,13 @@ split-string@^3.0.1, split-string@^3.0.2:
|
||||
dependencies:
|
||||
extend-shallow "^3.0.0"
|
||||
|
||||
sponge-case@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sponge-case/-/sponge-case-1.0.1.tgz#260833b86453883d974f84854cdb63aecc5aef4c"
|
||||
integrity sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@ -13081,7 +13055,7 @@ style-loader@0.23.1:
|
||||
loader-utils "^1.1.0"
|
||||
schema-utils "^1.0.0"
|
||||
|
||||
styled-components@^5.0.1, styled-components@^5.1.0:
|
||||
styled-components@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.2.1.tgz#6ed7fad2dc233825f64c719ffbdedd84ad79101a"
|
||||
integrity sha512-sBdgLWrCFTKtmZm/9x7jkIabjFNVzCUeKfoQsM6R3saImkUnjx0QYdLwJHBjY9ifEcmjDamJDVfknWm1yxZPxQ==
|
||||
@ -13156,6 +13130,13 @@ svgo@^1.0.0, svgo@^1.2.2:
|
||||
unquote "~1.1.1"
|
||||
util.promisify "~1.0.0"
|
||||
|
||||
swap-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-2.0.2.tgz#671aedb3c9c137e2985ef51c51f9e98445bf70d9"
|
||||
integrity sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
symbol-observable@^1.0.2, symbol-observable@^1.1.0, symbol-observable@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||
@ -13298,6 +13279,13 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
||||
|
||||
title-case@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/title-case/-/title-case-3.0.3.tgz#bc689b46f02e411f1d1e1d081f7c3deca0489982"
|
||||
integrity sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
@ -13462,11 +13450,16 @@ tslib@^1.10.0, tslib@^1.14.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@~2.0.0, tslib@~2.0.1:
|
||||
tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@~2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
|
||||
integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==
|
||||
|
||||
tslib@~2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
|
||||
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
version "3.17.1"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
|
||||
@ -13704,6 +13697,13 @@ upath@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
|
||||
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
|
||||
|
||||
upper-case-first@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324"
|
||||
integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
upper-case@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.1.tgz#6214d05e235dc817822464ccbae85822b3d8665f"
|
||||
@ -14092,7 +14092,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
|
||||
dependencies:
|
||||
iconv-lite "0.4.24"
|
||||
|
||||
whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1:
|
||||
whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868"
|
||||
integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==
|
||||
|
@ -53,10 +53,11 @@ type PersonalProject struct {
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
PublicOn sql.NullTime `json:"public_on"`
|
||||
}
|
||||
|
||||
type ProjectLabel struct {
|
||||
|
@ -5,13 +5,14 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createPersonalProject = `-- name: CreatePersonalProject :one
|
||||
INSERT INTO project(team_id, created_at, name) VALUES (null, $1, $2) RETURNING project_id, team_id, created_at, name
|
||||
INSERT INTO project(team_id, created_at, name) VALUES (null, $1, $2) RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type CreatePersonalProjectParams struct {
|
||||
@ -27,6 +28,7 @@ func (q *Queries) CreatePersonalProject(ctx context.Context, arg CreatePersonalP
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -78,7 +80,7 @@ func (q *Queries) CreateProjectMember(ctx context.Context, arg CreateProjectMemb
|
||||
}
|
||||
|
||||
const createTeamProject = `-- name: CreateTeamProject :one
|
||||
INSERT INTO project(team_id, created_at, name) VALUES ($1, $2, $3) RETURNING project_id, team_id, created_at, name
|
||||
INSERT INTO project(team_id, created_at, name) VALUES ($1, $2, $3) RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type CreateTeamProjectParams struct {
|
||||
@ -95,6 +97,7 @@ func (q *Queries) CreateTeamProject(ctx context.Context, arg CreateTeamProjectPa
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -132,7 +135,7 @@ func (q *Queries) DeleteProjectMember(ctx context.Context, arg DeleteProjectMemb
|
||||
}
|
||||
|
||||
const getAllProjectsForTeam = `-- name: GetAllProjectsForTeam :many
|
||||
SELECT project_id, team_id, created_at, name FROM project WHERE team_id = $1
|
||||
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error) {
|
||||
@ -149,6 +152,7 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -164,7 +168,7 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
|
||||
}
|
||||
|
||||
const getAllTeamProjects = `-- name: GetAllTeamProjects :many
|
||||
SELECT project_id, team_id, created_at, name FROM project WHERE team_id IS NOT null
|
||||
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE team_id IS NOT null
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
|
||||
@ -181,6 +185,7 @@ func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -196,7 +201,7 @@ func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
|
||||
}
|
||||
|
||||
const getAllVisibleProjectsForUserID = `-- name: GetAllVisibleProjectsForUserID :many
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name FROM project LEFT JOIN
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on FROM project LEFT JOIN
|
||||
project_member ON project_member.project_id = project.project_id WHERE project_member.user_id = $1
|
||||
`
|
||||
|
||||
@ -214,6 +219,7 @@ func (q *Queries) GetAllVisibleProjectsForUserID(ctx context.Context, userID uui
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -292,7 +298,7 @@ func (q *Queries) GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.
|
||||
}
|
||||
|
||||
const getPersonalProjectsForUserID = `-- name: GetPersonalProjectsForUserID :many
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name FROM project
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on FROM project
|
||||
LEFT JOIN personal_project ON personal_project.project_id = project.project_id
|
||||
WHERE personal_project.user_id = $1
|
||||
`
|
||||
@ -311,6 +317,7 @@ func (q *Queries) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -326,7 +333,7 @@ func (q *Queries) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.
|
||||
}
|
||||
|
||||
const getProjectByID = `-- name: GetProjectByID :one
|
||||
SELECT project_id, team_id, created_at, name FROM project WHERE project_id = $1
|
||||
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) {
|
||||
@ -337,6 +344,7 @@ func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Proj
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -426,6 +434,17 @@ func (q *Queries) GetProjectRolesForUserID(ctx context.Context, userID uuid.UUID
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getPublicOn = `-- name: GetPublicOn :one
|
||||
SELECT public_on FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetPublicOn(ctx context.Context, projectID uuid.UUID) (sql.NullTime, error) {
|
||||
row := q.db.QueryRowContext(ctx, getPublicOn, projectID)
|
||||
var public_on sql.NullTime
|
||||
err := row.Scan(&public_on)
|
||||
return public_on, err
|
||||
}
|
||||
|
||||
const getRoleForProjectMemberByUserID = `-- name: GetRoleForProjectMemberByUserID :one
|
||||
SELECT code, role.name FROM project_member INNER JOIN role ON role.code = project_member.role_code
|
||||
WHERE user_id = $1 AND project_id = $2
|
||||
@ -469,6 +488,28 @@ func (q *Queries) GetUserRolesForProject(ctx context.Context, arg GetUserRolesFo
|
||||
return i, err
|
||||
}
|
||||
|
||||
const setPublicOn = `-- name: SetPublicOn :one
|
||||
UPDATE project SET public_on = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type SetPublicOnParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
PublicOn sql.NullTime `json:"public_on"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, setPublicOn, arg.ProjectID, arg.PublicOn)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateProjectMemberRole = `-- name: UpdateProjectMemberRole :one
|
||||
UPDATE project_member SET role_code = $3 WHERE project_id = $1 AND user_id = $2
|
||||
RETURNING project_member_id, project_id, user_id, added_at, role_code
|
||||
@ -494,7 +535,7 @@ func (q *Queries) UpdateProjectMemberRole(ctx context.Context, arg UpdateProject
|
||||
}
|
||||
|
||||
const updateProjectNameByID = `-- name: UpdateProjectNameByID :one
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type UpdateProjectNameByIDParams struct {
|
||||
@ -510,6 +551,7 @@ func (q *Queries) UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNa
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@ -100,6 +101,7 @@ type Querier interface {
|
||||
GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)
|
||||
GetProjectRolesForUserID(ctx context.Context, userID uuid.UUID) ([]GetProjectRolesForUserIDRow, error)
|
||||
GetProjectsForInvitedMember(ctx context.Context, email string) ([]uuid.UUID, error)
|
||||
GetPublicOn(ctx context.Context, projectID uuid.UUID) (sql.NullTime, error)
|
||||
GetRecentlyAssignedTaskForUserID(ctx context.Context, arg GetRecentlyAssignedTaskForUserIDParams) ([]Task, error)
|
||||
GetRoleForProjectMemberByUserID(ctx context.Context, arg GetRoleForProjectMemberByUserIDParams) (Role, error)
|
||||
GetRoleForTeamMember(ctx context.Context, arg GetRoleForTeamMemberParams) (Role, error)
|
||||
@ -132,6 +134,7 @@ type Querier interface {
|
||||
HasAnyUser(ctx context.Context) (bool, error)
|
||||
SetFirstUserActive(ctx context.Context) (UserAccount, error)
|
||||
SetInactiveLastMoveForTaskID(ctx context.Context, taskID uuid.UUID) error
|
||||
SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Project, error)
|
||||
SetTaskChecklistItemComplete(ctx context.Context, arg SetTaskChecklistItemCompleteParams) (TaskChecklistItem, error)
|
||||
SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams) (Task, error)
|
||||
SetTaskGroupName(ctx context.Context, arg SetTaskGroupNameParams) (TaskGroup, error)
|
||||
|
@ -77,3 +77,9 @@ SELECT p.team_id, COALESCE(tm.role_code, '') AS team_role, COALESCE(pm.role_code
|
||||
|
||||
-- name: CreatePersonalProjectLink :one
|
||||
INSERT INTO personal_project (project_id, user_id) VALUES ($1, $2) RETURNING *;
|
||||
|
||||
-- name: SetPublicOn :one
|
||||
UPDATE project SET public_on = $2 WHERE project_id = $1 RETURNING *;
|
||||
|
||||
-- name: GetPublicOn :one
|
||||
SELECT public_on FROM project WHERE project_id = $1;
|
||||
|
@ -57,7 +57,8 @@ type ResolverRoot interface {
|
||||
}
|
||||
|
||||
type DirectiveRoot struct {
|
||||
HasRole func(ctx context.Context, obj interface{}, next graphql.Resolver, roles []RoleLevel, level ActionLevel, typeArg ObjectType) (res interface{}, err error)
|
||||
HasRole func(ctx context.Context, obj interface{}, next graphql.Resolver, roles []RoleLevel, level ActionLevel, typeArg ObjectType) (res interface{}, err error)
|
||||
RequiresUser func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error)
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
@ -248,6 +249,7 @@ type ComplexityRoot struct {
|
||||
SetTaskChecklistItemComplete func(childComplexity int, input SetTaskChecklistItemComplete) int
|
||||
SetTaskComplete func(childComplexity int, input SetTaskComplete) int
|
||||
SortTaskGroup func(childComplexity int, input SortTaskGroup) int
|
||||
ToggleProjectVisibility func(childComplexity int, input ToggleProjectVisibility) int
|
||||
ToggleTaskLabel func(childComplexity int, input ToggleTaskLabelInput) int
|
||||
UnassignTask func(childComplexity int, input *UnassignTaskInput) int
|
||||
UpdateProjectLabel func(childComplexity int, input UpdateProjectLabel) int
|
||||
@ -327,6 +329,7 @@ type ComplexityRoot struct {
|
||||
Members func(childComplexity int) int
|
||||
Name func(childComplexity int) int
|
||||
Permission func(childComplexity int) int
|
||||
PublicOn func(childComplexity int) int
|
||||
TaskGroups func(childComplexity int) int
|
||||
Team func(childComplexity int) int
|
||||
}
|
||||
@ -476,6 +479,10 @@ type ComplexityRoot struct {
|
||||
TeamID func(childComplexity int) int
|
||||
}
|
||||
|
||||
ToggleProjectVisibilityPayload struct {
|
||||
Project func(childComplexity int) int
|
||||
}
|
||||
|
||||
ToggleTaskLabelPayload struct {
|
||||
Active func(childComplexity int) int
|
||||
Task func(childComplexity int) int
|
||||
@ -547,6 +554,7 @@ type MutationResolver interface {
|
||||
CreateProject(ctx context.Context, input NewProject) (*db.Project, error)
|
||||
DeleteProject(ctx context.Context, input DeleteProject) (*DeleteProjectPayload, error)
|
||||
UpdateProjectName(ctx context.Context, input *UpdateProjectName) (*db.Project, error)
|
||||
ToggleProjectVisibility(ctx context.Context, input ToggleProjectVisibility) (*ToggleProjectVisibilityPayload, error)
|
||||
CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*db.ProjectLabel, error)
|
||||
DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*db.ProjectLabel, error)
|
||||
UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*db.ProjectLabel, error)
|
||||
@ -619,6 +627,7 @@ type ProjectResolver interface {
|
||||
TaskGroups(ctx context.Context, obj *db.Project) ([]db.TaskGroup, error)
|
||||
Members(ctx context.Context, obj *db.Project) ([]Member, error)
|
||||
InvitedMembers(ctx context.Context, obj *db.Project) ([]InvitedMember, error)
|
||||
PublicOn(ctx context.Context, obj *db.Project) (*time.Time, error)
|
||||
Permission(ctx context.Context, obj *db.Project) (*ProjectPermission, error)
|
||||
Labels(ctx context.Context, obj *db.Project) ([]db.ProjectLabel, error)
|
||||
}
|
||||
@ -1624,6 +1633,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Mutation.SortTaskGroup(childComplexity, args["input"].(SortTaskGroup)), true
|
||||
|
||||
case "Mutation.toggleProjectVisibility":
|
||||
if e.complexity.Mutation.ToggleProjectVisibility == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Mutation_toggleProjectVisibility_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.ToggleProjectVisibility(childComplexity, args["input"].(ToggleProjectVisibility)), true
|
||||
|
||||
case "Mutation.toggleTaskLabel":
|
||||
if e.complexity.Mutation.ToggleTaskLabel == nil {
|
||||
break
|
||||
@ -2098,6 +2119,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Project.Permission(childComplexity), true
|
||||
|
||||
case "Project.publicOn":
|
||||
if e.complexity.Project.PublicOn == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Project.PublicOn(childComplexity), true
|
||||
|
||||
case "Project.taskGroups":
|
||||
if e.complexity.Project.TaskGroups == nil {
|
||||
break
|
||||
@ -2763,6 +2791,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.TeamRole.TeamID(childComplexity), true
|
||||
|
||||
case "ToggleProjectVisibilityPayload.project":
|
||||
if e.complexity.ToggleProjectVisibilityPayload.Project == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ToggleProjectVisibilityPayload.Project(childComplexity), true
|
||||
|
||||
case "ToggleTaskLabelPayload.active":
|
||||
if e.complexity.ToggleTaskLabelPayload.Active == nil {
|
||||
break
|
||||
@ -3158,6 +3193,7 @@ type Project {
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
invitedMembers: [InvitedMember!]!
|
||||
publicOn: Time
|
||||
permission: ProjectPermission!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
@ -3294,6 +3330,7 @@ enum ObjectType {
|
||||
}
|
||||
|
||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
|
||||
directive @requiresUser on FIELD_DEFINITION
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
@ -3301,7 +3338,7 @@ type Query {
|
||||
invitedUsers: [InvitedUserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!):
|
||||
Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
|
||||
Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
@ -3309,7 +3346,7 @@ type Query {
|
||||
myTasks(input: MyTasks!): MyTasksPayload!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: MePayload!
|
||||
me: MePayload
|
||||
}
|
||||
|
||||
|
||||
@ -3427,6 +3464,16 @@ extend type Mutation {
|
||||
DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateProjectName(input: UpdateProjectName):
|
||||
Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleProjectVisibility(input: ToggleProjectVisibility!): ToggleProjectVisibilityPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input ToggleProjectVisibility {
|
||||
projectID: UUID!
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
@ -4558,6 +4605,21 @@ func (ec *executionContext) field_Mutation_sortTaskGroup_args(ctx context.Contex
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_toggleProjectVisibility_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 ToggleProjectVisibility
|
||||
if tmp, ok := rawArgs["input"]; ok {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input"))
|
||||
arg0, err = ec.unmarshalNToggleProjectVisibility2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibility(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["input"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_toggleTaskLabel_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
@ -7744,6 +7806,80 @@ func (ec *executionContext) _Mutation_updateProjectName(ctx context.Context, fie
|
||||
return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐProject(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_toggleProjectVisibility(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Mutation",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.field_Mutation_toggleProjectVisibility_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
fc.Args = args
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
directive0 := func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Mutation().ToggleProjectVisibility(rctx, args["input"].(ToggleProjectVisibility))
|
||||
}
|
||||
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||
roles, err := ec.unmarshalNRoleLevel2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleLevelᚄ(ctx, []interface{}{"ADMIN"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
level, err := ec.unmarshalNActionLevel2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐActionLevel(ctx, "PROJECT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ec.directives.HasRole == nil {
|
||||
return nil, errors.New("directive hasRole is not implemented")
|
||||
}
|
||||
return ec.directives.HasRole(ctx, nil, directive0, roles, level, typeArg)
|
||||
}
|
||||
|
||||
tmp, err := directive1(rctx)
|
||||
if err != nil {
|
||||
return nil, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
if tmp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if data, ok := tmp.(*ToggleProjectVisibilityPayload); ok {
|
||||
return data, nil
|
||||
}
|
||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/jordanknott/taskcafe/internal/graph.ToggleProjectVisibilityPayload`, tmp)
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*ToggleProjectVisibilityPayload)
|
||||
fc.Result = res
|
||||
return ec.marshalNToggleProjectVisibilityPayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibilityPayload(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_createProjectLabel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -12601,6 +12737,38 @@ func (ec *executionContext) _Project_invitedMembers(ctx context.Context, field g
|
||||
return ec.marshalNInvitedMember2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐInvitedMemberᚄ(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Project_publicOn(ctx context.Context, field graphql.CollectedField, obj *db.Project) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Project",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Project().PublicOn(rctx, obj)
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*time.Time)
|
||||
fc.Result = res
|
||||
return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Project_permission(ctx context.Context, field graphql.CollectedField, obj *db.Project) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -13224,40 +13392,8 @@ func (ec *executionContext) _Query_findProject(ctx context.Context, field graphq
|
||||
}
|
||||
fc.Args = args
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
directive0 := func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Query().FindProject(rctx, args["input"].(FindProject))
|
||||
}
|
||||
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||
roles, err := ec.unmarshalNRoleLevel2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleLevelᚄ(ctx, []interface{}{"ADMIN", "MEMBER"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
level, err := ec.unmarshalNActionLevel2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐActionLevel(ctx, "PROJECT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ec.directives.HasRole == nil {
|
||||
return nil, errors.New("directive hasRole is not implemented")
|
||||
}
|
||||
return ec.directives.HasRole(ctx, nil, directive0, roles, level, typeArg)
|
||||
}
|
||||
|
||||
tmp, err := directive1(rctx)
|
||||
if err != nil {
|
||||
return nil, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
if tmp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if data, ok := tmp.(*db.Project); ok {
|
||||
return data, nil
|
||||
}
|
||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/jordanknott/taskcafe/internal/db.Project`, tmp)
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Query().FindProject(rctx, args["input"].(FindProject))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
@ -13572,14 +13708,11 @@ func (ec *executionContext) _Query_me(ctx context.Context, field graphql.Collect
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*MePayload)
|
||||
fc.Result = res
|
||||
return ec.marshalNMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx, field.Selections, res)
|
||||
return ec.marshalOMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_notifications(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
@ -15885,6 +16018,41 @@ func (ec *executionContext) _TeamRole_roleCode(ctx context.Context, field graphq
|
||||
return ec.marshalNRoleCode2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleCode(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ToggleProjectVisibilityPayload_project(ctx context.Context, field graphql.CollectedField, obj *ToggleProjectVisibilityPayload) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "ToggleProjectVisibilityPayload",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Project, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*db.Project)
|
||||
fc.Result = res
|
||||
return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐProject(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ToggleTaskLabelPayload_active(ctx context.Context, field graphql.CollectedField, obj *ToggleTaskLabelPayload) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -19238,6 +19406,34 @@ func (ec *executionContext) unmarshalInputTaskPositionUpdate(ctx context.Context
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputToggleProjectVisibility(ctx context.Context, obj interface{}) (ToggleProjectVisibility, error) {
|
||||
var it ToggleProjectVisibility
|
||||
var asMap = obj.(map[string]interface{})
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
case "projectID":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("projectID"))
|
||||
it.ProjectID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "isPublic":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("isPublic"))
|
||||
it.IsPublic, err = ec.unmarshalNBoolean2bool(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputToggleTaskLabelInput(ctx context.Context, obj interface{}) (ToggleTaskLabelInput, error) {
|
||||
var it ToggleTaskLabelInput
|
||||
var asMap = obj.(map[string]interface{})
|
||||
@ -20841,6 +21037,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "toggleProjectVisibility":
|
||||
out.Values[i] = ec._Mutation_toggleProjectVisibility(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "createProjectLabel":
|
||||
out.Values[i] = ec._Mutation_createProjectLabel(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
@ -21541,6 +21742,17 @@ func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet,
|
||||
}
|
||||
return res
|
||||
})
|
||||
case "publicOn":
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._Project_publicOn(ctx, field, obj)
|
||||
return res
|
||||
})
|
||||
case "permission":
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
@ -21939,9 +22151,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
}
|
||||
}()
|
||||
res = ec._Query_me(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
})
|
||||
case "notifications":
|
||||
@ -22860,6 +23069,33 @@ func (ec *executionContext) _TeamRole(ctx context.Context, sel ast.SelectionSet,
|
||||
return out
|
||||
}
|
||||
|
||||
var toggleProjectVisibilityPayloadImplementors = []string{"ToggleProjectVisibilityPayload"}
|
||||
|
||||
func (ec *executionContext) _ToggleProjectVisibilityPayload(ctx context.Context, sel ast.SelectionSet, obj *ToggleProjectVisibilityPayload) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, toggleProjectVisibilityPayloadImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("ToggleProjectVisibilityPayload")
|
||||
case "project":
|
||||
out.Values[i] = ec._ToggleProjectVisibilityPayload_project(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
var toggleTaskLabelPayloadImplementors = []string{"ToggleTaskLabelPayload"}
|
||||
|
||||
func (ec *executionContext) _ToggleTaskLabelPayload(ctx context.Context, sel ast.SelectionSet, obj *ToggleTaskLabelPayload) graphql.Marshaler {
|
||||
@ -24186,20 +24422,6 @@ func (ec *executionContext) unmarshalNLogoutUser2githubᚗcomᚋjordanknottᚋta
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNMePayload2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx context.Context, sel ast.SelectionSet, v MePayload) graphql.Marshaler {
|
||||
return ec._MePayload(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx context.Context, sel ast.SelectionSet, v *MePayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._MePayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNMember2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMember(ctx context.Context, sel ast.SelectionSet, v Member) graphql.Marshaler {
|
||||
return ec._Member(ctx, sel, &v)
|
||||
}
|
||||
@ -25468,6 +25690,25 @@ func (ec *executionContext) marshalNTime2ᚖtimeᚐTime(ctx context.Context, sel
|
||||
return res
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNToggleProjectVisibility2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibility(ctx context.Context, v interface{}) (ToggleProjectVisibility, error) {
|
||||
res, err := ec.unmarshalInputToggleProjectVisibility(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNToggleProjectVisibilityPayload2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibilityPayload(ctx context.Context, sel ast.SelectionSet, v ToggleProjectVisibilityPayload) graphql.Marshaler {
|
||||
return ec._ToggleProjectVisibilityPayload(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNToggleProjectVisibilityPayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibilityPayload(ctx context.Context, sel ast.SelectionSet, v *ToggleProjectVisibilityPayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._ToggleProjectVisibilityPayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNToggleTaskLabelInput2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleTaskLabelInput(ctx context.Context, v interface{}) (ToggleTaskLabelInput, error) {
|
||||
res, err := ec.unmarshalInputToggleTaskLabelInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
@ -26081,6 +26322,13 @@ func (ec *executionContext) unmarshalODeleteTaskComment2ᚖgithubᚗcomᚋjordan
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx context.Context, sel ast.SelectionSet, v *MePayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._MePayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOProfileIcon2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐProfileIcon(ctx context.Context, sel ast.SelectionSet, v *ProfileIcon) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
|
@ -46,6 +46,12 @@ func NewHandler(repo db.Repository, emailConfig utils.EmailConfig) http.Handler
|
||||
}
|
||||
*/
|
||||
|
||||
userID, ok := GetUserID(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New("user must be logged in")
|
||||
}
|
||||
log.Info("has role")
|
||||
|
||||
var subjectID uuid.UUID
|
||||
in := graphql.GetFieldContext(ctx).Args["input"]
|
||||
val := reflect.ValueOf(in) // could be any underlying type
|
||||
@ -78,7 +84,7 @@ func NewHandler(repo db.Repository, emailConfig utils.EmailConfig) http.Handler
|
||||
// TODO: add config setting to disable personal projects
|
||||
return next(ctx)
|
||||
}
|
||||
subjectID, ok := subjectField.Interface().(uuid.UUID)
|
||||
subjectID, ok = subjectField.Interface().(uuid.UUID)
|
||||
if !ok {
|
||||
logger.New(ctx).Error("error while casting subject UUID")
|
||||
return nil, errors.New("error while casting subject uuid")
|
||||
@ -130,10 +136,6 @@ func NewHandler(repo db.Repository, emailConfig utils.EmailConfig) http.Handler
|
||||
},
|
||||
}
|
||||
} else if level == ActionLevelTeam {
|
||||
userID, ok := GetUserID(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New("user id is missing")
|
||||
}
|
||||
role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID})
|
||||
if err != nil {
|
||||
logger.New(ctx).WithError(err).Error("error while getting team roles for user ID")
|
||||
@ -270,3 +272,23 @@ const (
|
||||
TASK_CHECKLIST_ADDED int32 = 9
|
||||
TASK_CHECKLIST_REMOVED int32 = 10
|
||||
)
|
||||
|
||||
func NotAuthorized() error {
|
||||
return &gqlerror.Error{
|
||||
Message: "Not authorized",
|
||||
Extensions: map[string]interface{}{
|
||||
"code": "UNAUTHENTICATED",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func IsProjectPublic(ctx context.Context, repo db.Repository, projectID uuid.UUID) (bool, error) {
|
||||
publicOn, err := repo.GetPublicOn(ctx, projectID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !publicOn.Valid {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
@ -448,6 +448,15 @@ type TeamRole struct {
|
||||
RoleCode RoleCode `json:"roleCode"`
|
||||
}
|
||||
|
||||
type ToggleProjectVisibility struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
IsPublic bool `json:"isPublic"`
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload struct {
|
||||
Project *db.Project `json:"project"`
|
||||
}
|
||||
|
||||
type ToggleTaskLabelInput struct {
|
||||
TaskID uuid.UUID `json:"taskID"`
|
||||
ProjectLabelID uuid.UUID `json:"projectLabelID"`
|
||||
|
@ -119,6 +119,7 @@ type Project {
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
invitedMembers: [InvitedMember!]!
|
||||
publicOn: Time
|
||||
permission: ProjectPermission!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
@ -255,6 +256,7 @@ enum ObjectType {
|
||||
}
|
||||
|
||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
|
||||
directive @requiresUser on FIELD_DEFINITION
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
@ -262,7 +264,7 @@ type Query {
|
||||
invitedUsers: [InvitedUserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!):
|
||||
Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
|
||||
Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
@ -270,7 +272,7 @@ type Query {
|
||||
myTasks(input: MyTasks!): MyTasksPayload!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: MePayload!
|
||||
me: MePayload
|
||||
}
|
||||
|
||||
|
||||
@ -388,6 +390,16 @@ extend type Mutation {
|
||||
DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateProjectName(input: UpdateProjectName):
|
||||
Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleProjectVisibility(input: ToggleProjectVisibility!): ToggleProjectVisibilityPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input ToggleProjectVisibility {
|
||||
projectID: UUID!
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
@ -982,3 +994,4 @@ type DeleteUserAccountPayload {
|
||||
ok: Boolean!
|
||||
userAccount: UserAccount!
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,15 @@ func (r *mutationResolver) UpdateProjectName(ctx context.Context, input *UpdateP
|
||||
return &project, nil
|
||||
}
|
||||
|
||||
func (r *mutationResolver) ToggleProjectVisibility(ctx context.Context, input ToggleProjectVisibility) (*ToggleProjectVisibilityPayload, error) {
|
||||
if input.IsPublic {
|
||||
project, err := r.Repository.SetPublicOn(ctx, db.SetPublicOnParams{ProjectID: input.ProjectID, PublicOn: sql.NullTime{Valid: true, Time: time.Now().UTC()}})
|
||||
return &ToggleProjectVisibilityPayload{Project: &project}, err
|
||||
}
|
||||
project, err := r.Repository.SetPublicOn(ctx, db.SetPublicOnParams{ProjectID: input.ProjectID, PublicOn: sql.NullTime{Valid: false, Time: time.Time{}}})
|
||||
return &ToggleProjectVisibilityPayload{Project: &project}, err
|
||||
}
|
||||
|
||||
func (r *mutationResolver) CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*db.ProjectLabel, error) {
|
||||
createdAt := time.Now().UTC()
|
||||
|
||||
@ -1206,6 +1215,13 @@ func (r *projectResolver) InvitedMembers(ctx context.Context, obj *db.Project) (
|
||||
return invited, err
|
||||
}
|
||||
|
||||
func (r *projectResolver) PublicOn(ctx context.Context, obj *db.Project) (*time.Time, error) {
|
||||
if obj.PublicOn.Valid {
|
||||
return &obj.PublicOn.Time, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *projectResolver) Permission(ctx context.Context, obj *db.Project) (*ProjectPermission, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
@ -1277,12 +1293,19 @@ func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserA
|
||||
|
||||
func (r *queryResolver) FindProject(ctx context.Context, input FindProject) (*db.Project, error) {
|
||||
logger.New(ctx).Info("finding project user")
|
||||
_, isLoggedIn := GetUser(ctx)
|
||||
if !isLoggedIn {
|
||||
isPublic, _ := IsProjectPublic(ctx, r.Repository, input.ProjectID)
|
||||
if !isPublic {
|
||||
return &db.Project{}, NotAuthorized()
|
||||
}
|
||||
}
|
||||
project, err := r.Repository.GetProjectByID(ctx, input.ProjectID)
|
||||
if err == sql.ErrNoRows {
|
||||
return &db.Project{}, &gqlerror.Error{
|
||||
Message: "Project not found",
|
||||
Extensions: map[string]interface{}{
|
||||
"code": "11-404",
|
||||
"code": "NOT_FOUND",
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1497,7 +1520,7 @@ func (r *queryResolver) TaskGroups(ctx context.Context) ([]db.TaskGroup, error)
|
||||
func (r *queryResolver) Me(ctx context.Context) (*MePayload, error) {
|
||||
userID, ok := GetUserID(ctx)
|
||||
if !ok {
|
||||
return &MePayload{}, fmt.Errorf("internal server error")
|
||||
return nil, nil
|
||||
}
|
||||
user, err := r.Repository.GetUserAccountByID(ctx, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
|
@ -119,6 +119,7 @@ type Project {
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
invitedMembers: [InvitedMember!]!
|
||||
publicOn: Time
|
||||
permission: ProjectPermission!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ enum ObjectType {
|
||||
}
|
||||
|
||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
|
||||
directive @requiresUser on FIELD_DEFINITION
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
@ -32,7 +33,7 @@ type Query {
|
||||
invitedUsers: [InvitedUserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!):
|
||||
Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
|
||||
Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
@ -40,7 +41,7 @@ type Query {
|
||||
myTasks(input: MyTasks!): MyTasksPayload!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: MePayload!
|
||||
me: MePayload
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,6 +4,16 @@ extend type Mutation {
|
||||
DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateProjectName(input: UpdateProjectName):
|
||||
Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleProjectVisibility(input: ToggleProjectVisibility!): ToggleProjectVisibilityPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input ToggleProjectVisibility {
|
||||
projectID: UUID!
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
|
@ -18,6 +18,7 @@ type AuthenticationMiddleware struct {
|
||||
// Middleware returns the middleware handler
|
||||
func (m *AuthenticationMiddleware) Middleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Info("middleware")
|
||||
requestID := uuid.New()
|
||||
foundToken := true
|
||||
tokenRaw := ""
|
||||
@ -25,42 +26,26 @@ func (m *AuthenticationMiddleware) Middleware(next http.Handler) http.Handler {
|
||||
if err != nil {
|
||||
if err == http.ErrNoCookie {
|
||||
foundToken = false
|
||||
} else {
|
||||
log.WithError(err).Error("unknown error")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
if !foundToken {
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
log.WithError(err).Error("no auth token found in cookie or authorization header")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
if token != "" {
|
||||
tokenRaw = token
|
||||
}
|
||||
tokenRaw = token
|
||||
} else {
|
||||
tokenRaw = c.Value
|
||||
}
|
||||
authTokenID := uuid.MustParse(tokenRaw)
|
||||
token, err := m.repo.GetAuthTokenByID(r.Context(), authTokenID)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{
|
||||
"data": {},
|
||||
"errors": [
|
||||
{
|
||||
"extensions": {
|
||||
"code": "UNAUTHENTICATED"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`))
|
||||
return
|
||||
authTokenID, err := uuid.Parse(tokenRaw)
|
||||
log.Info("checking if logged in")
|
||||
ctx := r.Context()
|
||||
if err == nil {
|
||||
token, err := m.repo.GetAuthTokenByID(r.Context(), authTokenID)
|
||||
if err == nil {
|
||||
ctx = context.WithValue(ctx, utils.UserIDKey, token.UserID)
|
||||
}
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), utils.UserIDKey, token.UserID)
|
||||
// ctx = context.WithValue(ctx, utils.RestrictedModeKey, accessClaims.Restricted)
|
||||
// ctx = context.WithValue(ctx, utils.OrgRoleKey, accessClaims.OrgRole)
|
||||
ctx = context.WithValue(ctx, utils.ReqIDKey, requestID)
|
||||
|
1
migrations/0065_add-public_on-to-project.up.sql
Normal file
1
migrations/0065_add-public_on-to-project.up.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE project ADD COLUMN public_on timestamptz;
|
Loading…
Reference in New Issue
Block a user