feat: change url structure to use short ids instead of full uuids

This commit is contained in:
Jordan Knott 2021-11-04 13:36:46 -05:00
parent f9a5007104
commit df6140a10f
32 changed files with 613 additions and 289 deletions

View File

@ -70,11 +70,10 @@ const Routes: React.FC = () => {
<Route exact path="/confirm" component={Confirm} /> <Route exact path="/confirm" component={Confirm} />
<Switch> <Switch>
<MainContent> <MainContent>
<Route path="/projects/:projectID" component={Project} /> <Route path="/p/:projectID" component={Project} />
<UserRequiredRoute> <UserRequiredRoute>
<Route exact path="/" component={Dashboard} /> <Route exact path="/" component={Projects} />
<Route exact path="/projects" component={Projects} />
<Route path="/teams/:teamID" component={Teams} /> <Route path="/teams/:teamID" component={Teams} />
<Route path="/profile" component={Profile} /> <Route path="/profile" component={Profile} />
<Route path="/admin" component={Admin} /> <Route path="/admin" component={Admin} />

View File

@ -429,6 +429,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
createTask: { createTask: {
__typename: 'Task', __typename: 'Task',
id: `${Math.round(Math.random() * -1000000)}`, id: `${Math.round(Math.random() * -1000000)}`,
shortId: '',
name, name,
watched: false, watched: false,
complete: false, complete: false,
@ -605,7 +606,7 @@ const ProjectBoard: React.FC<ProjectBoardProps> = ({ projectID, onCardLabelClick
<SimpleLists <SimpleLists
isPublic={user === null} isPublic={user === null}
onTaskClick={(task) => { onTaskClick={(task) => {
history.push(`${match.url}/c/${task.id}`); history.push(`${match.url}/c/${task.shortId}`);
}} }}
onCardLabelClick={onCardLabelClick ?? NOOP} onCardLabelClick={onCardLabelClick ?? NOOP}
cardLabelVariant={cardLabelVariant ?? 'large'} cardLabelVariant={cardLabelVariant ?? 'large'}

View File

@ -87,7 +87,7 @@ const Project = () => {
} }
} }
}), }),
{ projectID }, { projectID: data ? data.findProject.id : '' },
), ),
}); });
@ -100,7 +100,7 @@ const Project = () => {
produce(cache, (draftCache) => { produce(cache, (draftCache) => {
draftCache.findProject.name = newName.data?.updateProjectName.name ?? ''; draftCache.findProject.name = newName.data?.updateProjectName.name ?? '';
}), }),
{ projectID }, { projectID: data ? data.findProject.id : '' },
); );
}, },
}); });
@ -123,7 +123,7 @@ const Project = () => {
]; ];
} }
}), }),
{ projectID }, { projectID: data ? data.findProject.id : '' },
); );
}, },
}); });
@ -138,7 +138,7 @@ const Project = () => {
(m) => m.email !== response.data?.deleteInvitedProjectMember.invitedMember.email ?? '', (m) => m.email !== response.data?.deleteInvitedProjectMember.invitedMember.email ?? '',
); );
}), }),
{ projectID }, { projectID: data ? data.findProject.id : '' },
); );
}, },
}); });
@ -153,7 +153,7 @@ const Project = () => {
(m) => m.id !== response.data?.deleteProjectMember.member.id, (m) => m.id !== response.data?.deleteProjectMember.member.id,
); );
}), }),
{ projectID }, { projectID: data ? data.findProject.id : '' },
); );
}, },
}); });
@ -171,29 +171,29 @@ const Project = () => {
<> <>
<GlobalTopNavbar <GlobalTopNavbar
onChangeRole={(userID, roleCode) => { onChangeRole={(userID, roleCode) => {
updateProjectMemberRole({ variables: { userID, roleCode, projectID } }); updateProjectMemberRole({ variables: { userID, roleCode, projectID: data ? data.findProject.id : '' } });
}} }}
onChangeProjectOwner={() => { onChangeProjectOwner={() => {
hidePopup(); hidePopup();
}} }}
onRemoveFromBoard={(userID) => { onRemoveFromBoard={(userID) => {
deleteProjectMember({ variables: { userID, projectID } }); deleteProjectMember({ variables: { userID, projectID: data ? data.findProject.id : '' } });
hidePopup(); hidePopup();
}} }}
onRemoveInvitedFromBoard={(email) => { onRemoveInvitedFromBoard={(email) => {
deleteInvitedProjectMember({ variables: { projectID, email } }); deleteInvitedProjectMember({ variables: { projectID: data ? data.findProject.id : '', email } });
hidePopup(); hidePopup();
}} }}
onSaveProjectName={(projectName) => { onSaveProjectName={(projectName) => {
updateProjectName({ variables: { projectID, name: projectName } }); updateProjectName({ variables: { projectID: data ? data.findProject.id : '', name: projectName } });
}} }}
onInviteUser={($target) => { onInviteUser={($target) => {
showPopup( showPopup(
$target, $target,
<UserManagementPopup <UserManagementPopup
projectID={projectID} projectID={data ? data.findProject.id : ''}
onInviteProjectMembers={(members) => { onInviteProjectMembers={(members) => {
inviteProjectMembers({ variables: { projectID, members } }); inviteProjectMembers({ variables: { projectID: data ? data.findProject.id : '', members } });
hidePopup(); hidePopup();
}} }}
users={data.users} users={data.users}

View File

@ -307,7 +307,7 @@ const Projects = () => {
<ProjectList> <ProjectList>
{personalProjects.map((project, idx) => ( {personalProjects.map((project, idx) => (
<ProjectListItem key={project.id}> <ProjectListItem key={project.id}>
<ProjectTile color={colors[idx % 5]} to={`/projects/${project.id}`}> <ProjectTile color={colors[idx % 5]} to={`/p/${project.shortId}`}>
<ProjectTileFade /> <ProjectTileFade />
<ProjectTileDetails> <ProjectTileDetails>
<ProjectTileName>{project.name}</ProjectTileName> <ProjectTileName>{project.name}</ProjectTileName>
@ -351,7 +351,7 @@ const Projects = () => {
<ProjectList> <ProjectList>
{team.projects.map((project, idx) => ( {team.projects.map((project, idx) => (
<ProjectListItem key={project.id}> <ProjectListItem key={project.id}>
<ProjectTile color={colors[idx % 5]} to={`/projects/${project.id}`}> <ProjectTile color={colors[idx % 5]} to={`/p/${project.shortId}`}>
<ProjectTileFade /> <ProjectTileFade />
<ProjectTileDetails> <ProjectTileDetails>
<ProjectTileName>{project.name}</ProjectTileName> <ProjectTileName>{project.name}</ProjectTileName>

View File

@ -331,7 +331,7 @@ const Notification: React.FC<NotificationProps> = ({ causedBy, createdAt, data,
prefix.push(<UserCircle width={14} height={16} />); prefix.push(<UserCircle width={14} height={16} />);
prefix.push(<NotificationPrefix>Assigned </NotificationPrefix>); prefix.push(<NotificationPrefix>Assigned </NotificationPrefix>);
prefix.push(<span>you to the task "{dataMap.get('TaskName')}"</span>); prefix.push(<span>you to the task "{dataMap.get('TaskName')}"</span>);
link = `/projects/${dataMap.get('ProjectID')}/board/c/${dataMap.get('TaskID')}`; link = `/p/${dataMap.get('ProjectID')}/board/c/${dataMap.get('TaskID')}`;
break; break;
default: default:
throw new Error('unknown action type'); throw new Error('unknown action type');

View File

@ -278,11 +278,13 @@ export type DuplicateTaskGroupPayload = {
}; };
export type FindProject = { export type FindProject = {
projectID: Scalars['UUID']; projectID?: Maybe<Scalars['UUID']>;
projectShortID?: Maybe<Scalars['String']>;
}; };
export type FindTask = { export type FindTask = {
taskID: Scalars['UUID']; taskID?: Maybe<Scalars['UUID']>;
taskShortID?: Maybe<Scalars['String']>;
}; };
export type FindTeam = { export type FindTeam = {
@ -908,6 +910,7 @@ export type ProfileIcon = {
export type Project = { export type Project = {
__typename?: 'Project'; __typename?: 'Project';
id: Scalars['ID']; id: Scalars['ID'];
shortId: Scalars['String'];
createdAt: Scalars['Time']; createdAt: Scalars['Time'];
name: Scalars['String']; name: Scalars['String'];
team?: Maybe<Team>; team?: Maybe<Team>;
@ -1068,6 +1071,7 @@ export type Subscription = {
export type Task = { export type Task = {
__typename?: 'Task'; __typename?: 'Task';
id: Scalars['ID']; id: Scalars['ID'];
shortId: Scalars['String'];
taskGroup: TaskGroup; taskGroup: TaskGroup;
createdAt: Scalars['Time']; createdAt: Scalars['Time'];
name: Scalars['String']; name: Scalars['String'];
@ -1419,7 +1423,7 @@ export type CreateProjectMutation = (
{ __typename?: 'Mutation' } { __typename?: 'Mutation' }
& { createProject: ( & { createProject: (
{ __typename?: 'Project' } { __typename?: 'Project' }
& Pick<Project, 'id' | 'name'> & Pick<Project, 'id' | 'shortId' | 'name'>
& { team?: Maybe<( & { team?: Maybe<(
{ __typename?: 'Team' } { __typename?: 'Team' }
& Pick<Team, 'id' | 'name'> & Pick<Team, 'id' | 'name'>
@ -1509,7 +1513,7 @@ export type DeleteTaskGroupMutation = (
); );
export type FindProjectQueryVariables = Exact<{ export type FindProjectQueryVariables = Exact<{
projectID: Scalars['UUID']; projectID: Scalars['String'];
}>; }>;
@ -1517,7 +1521,7 @@ export type FindProjectQuery = (
{ __typename?: 'Query' } { __typename?: 'Query' }
& { findProject: ( & { findProject: (
{ __typename?: 'Project' } { __typename?: 'Project' }
& Pick<Project, 'name' | 'publicOn'> & Pick<Project, 'id' | 'name' | 'publicOn'>
& { team?: Maybe<( & { team?: Maybe<(
{ __typename?: 'Team' } { __typename?: 'Team' }
& Pick<Team, 'id'> & Pick<Team, 'id'>
@ -1584,7 +1588,7 @@ export type FindProjectQuery = (
); );
export type FindTaskQueryVariables = Exact<{ export type FindTaskQueryVariables = Exact<{
taskID: Scalars['UUID']; taskID: Scalars['String'];
}>; }>;
@ -1592,7 +1596,7 @@ export type FindTaskQuery = (
{ __typename?: 'Query' } { __typename?: 'Query' }
& { findTask: ( & { findTask: (
{ __typename?: 'Task' } { __typename?: 'Task' }
& Pick<Task, 'id' | 'name' | 'watched' | 'description' | 'dueDate' | 'position' | 'complete' | 'hasTime'> & Pick<Task, 'id' | 'shortId' | 'name' | 'watched' | 'description' | 'dueDate' | 'position' | 'complete' | 'hasTime'>
& { taskGroup: ( & { taskGroup: (
{ __typename?: 'TaskGroup' } { __typename?: 'TaskGroup' }
& Pick<TaskGroup, 'id' | 'name'> & Pick<TaskGroup, 'id' | 'name'>
@ -1668,7 +1672,7 @@ export type FindTaskQuery = (
export type TaskFieldsFragment = ( export type TaskFieldsFragment = (
{ __typename?: 'Task' } { __typename?: 'Task' }
& Pick<Task, 'id' | 'name' | 'description' | 'dueDate' | 'hasTime' | 'complete' | 'watched' | 'completedAt' | 'position'> & Pick<Task, 'id' | 'shortId' | 'name' | 'description' | 'dueDate' | 'hasTime' | 'complete' | 'watched' | 'completedAt' | 'position'>
& { badges: ( & { badges: (
{ __typename?: 'TaskBadges' } { __typename?: 'TaskBadges' }
& { checklist?: Maybe<( & { checklist?: Maybe<(
@ -1715,7 +1719,7 @@ export type GetProjectsQuery = (
& Pick<Team, 'id' | 'name' | 'createdAt'> & Pick<Team, 'id' | 'name' | 'createdAt'>
)>, projects: Array<( )>, projects: Array<(
{ __typename?: 'Project' } { __typename?: 'Project' }
& Pick<Project, 'id' | 'name'> & Pick<Project, 'id' | 'shortId' | 'name'>
& { team?: Maybe<( & { team?: Maybe<(
{ __typename?: 'Team' } { __typename?: 'Team' }
& Pick<Team, 'id' | 'name'> & Pick<Team, 'id' | 'name'>
@ -1785,7 +1789,7 @@ export type MyTasksQuery = (
{ __typename?: 'MyTasksPayload' } { __typename?: 'MyTasksPayload' }
& { tasks: Array<( & { tasks: Array<(
{ __typename?: 'Task' } { __typename?: 'Task' }
& Pick<Task, 'id' | 'name' | 'dueDate' | 'hasTime' | 'complete' | 'completedAt'> & Pick<Task, 'id' | 'shortId' | 'name' | 'dueDate' | 'hasTime' | 'complete' | 'completedAt'>
& { taskGroup: ( & { taskGroup: (
{ __typename?: 'TaskGroup' } { __typename?: 'TaskGroup' }
& Pick<TaskGroup, 'id' | 'name'> & Pick<TaskGroup, 'id' | 'name'>
@ -2859,6 +2863,7 @@ export type UsersQuery = (
export const TaskFieldsFragmentDoc = gql` export const TaskFieldsFragmentDoc = gql`
fragment TaskFields on Task { fragment TaskFields on Task {
id id
shortId
name name
description description
dueDate dueDate
@ -2988,6 +2993,7 @@ export const CreateProjectDocument = gql`
mutation createProject($teamID: UUID, $name: String!) { mutation createProject($teamID: UUID, $name: String!) {
createProject(input: {teamID: $teamID, name: $name}) { createProject(input: {teamID: $teamID, name: $name}) {
id id
shortId
name name
team { team {
id id
@ -3215,8 +3221,9 @@ export type DeleteTaskGroupMutationHookResult = ReturnType<typeof useDeleteTaskG
export type DeleteTaskGroupMutationResult = Apollo.MutationResult<DeleteTaskGroupMutation>; export type DeleteTaskGroupMutationResult = Apollo.MutationResult<DeleteTaskGroupMutation>;
export type DeleteTaskGroupMutationOptions = Apollo.BaseMutationOptions<DeleteTaskGroupMutation, DeleteTaskGroupMutationVariables>; export type DeleteTaskGroupMutationOptions = Apollo.BaseMutationOptions<DeleteTaskGroupMutation, DeleteTaskGroupMutationVariables>;
export const FindProjectDocument = gql` export const FindProjectDocument = gql`
query findProject($projectID: UUID!) { query findProject($projectID: String!) {
findProject(input: {projectID: $projectID}) { findProject(input: {projectShortID: $projectID}) {
id
name name
publicOn publicOn
team { team {
@ -3332,9 +3339,10 @@ export type FindProjectQueryHookResult = ReturnType<typeof useFindProjectQuery>;
export type FindProjectLazyQueryHookResult = ReturnType<typeof useFindProjectLazyQuery>; export type FindProjectLazyQueryHookResult = ReturnType<typeof useFindProjectLazyQuery>;
export type FindProjectQueryResult = Apollo.QueryResult<FindProjectQuery, FindProjectQueryVariables>; export type FindProjectQueryResult = Apollo.QueryResult<FindProjectQuery, FindProjectQueryVariables>;
export const FindTaskDocument = gql` export const FindTaskDocument = gql`
query findTask($taskID: UUID!) { query findTask($taskID: String!) {
findTask(input: {taskID: $taskID}) { findTask(input: {taskShortID: $taskID}) {
id id
shortId
name name
watched watched
description description
@ -3477,6 +3485,7 @@ export const GetProjectsDocument = gql`
} }
projects { projects {
id id
shortId
name name
team { team {
id id
@ -3625,6 +3634,7 @@ export const MyTasksDocument = gql`
myTasks(input: {status: $status, sort: $sort}) { myTasks(input: {status: $status, sort: $sort}) {
tasks { tasks {
id id
shortId
taskGroup { taskGroup {
id id
name name

View File

@ -1,6 +1,7 @@
mutation createProject($teamID: UUID, $name: String!) { mutation createProject($teamID: UUID, $name: String!) {
createProject(input: {teamID: $teamID, name: $name}) { createProject(input: {teamID: $teamID, name: $name}) {
id id
shortId
name name
team { team {
id id

View File

@ -2,8 +2,9 @@ import gql from 'graphql-tag';
import TASK_FRAGMENT from './fragments/task'; import TASK_FRAGMENT from './fragments/task';
const FIND_PROJECT_QUERY = gql` const FIND_PROJECT_QUERY = gql`
query findProject($projectID: UUID!) { query findProject($projectID: String!) {
findProject(input: { projectID: $projectID }) { findProject(input: { projectShortID: $projectID }) {
id
name name
publicOn publicOn
team { team {

View File

@ -1,6 +1,7 @@
query findTask($taskID: UUID!) { query findTask($taskID: String!) {
findTask(input: {taskID: $taskID}) { findTask(input: {taskShortID: $taskID}) {
id id
shortId
name name
watched watched
description description

View File

@ -3,6 +3,7 @@ import gql from 'graphql-tag';
const TASK_FRAGMENT = gql` const TASK_FRAGMENT = gql`
fragment TaskFields on Task { fragment TaskFields on Task {
id id
shortId
name name
description description
dueDate dueDate

View File

@ -10,6 +10,7 @@ query getProjects {
} }
projects { projects {
id id
shortId
name name
team { team {
id id

View File

@ -6,6 +6,7 @@ query myTasks($status: MyTasksStatus!, $sort: MyTasksSort!) {
myTasks(input: { status: $status, sort: $sort }) { myTasks(input: { status: $status, sort: $sort }) {
tasks { tasks {
id id
shortId
taskGroup { taskGroup {
id id
name name

View File

@ -103,6 +103,7 @@ type TaskComment = {
type Task = { type Task = {
id: string; id: string;
shortId: string;
taskGroup: InnerTaskGroup; taskGroup: InnerTaskGroup;
name: string; name: string;
watched?: boolean; watched?: boolean;

View File

@ -86,6 +86,7 @@ type Project struct {
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
Name string `json:"name"` Name string `json:"name"`
PublicOn sql.NullTime `json:"public_on"` PublicOn sql.NullTime `json:"public_on"`
ShortID string `json:"short_id"`
} }
type ProjectLabel struct { type ProjectLabel struct {
@ -132,6 +133,7 @@ type Task struct {
Complete bool `json:"complete"` Complete bool `json:"complete"`
CompletedAt sql.NullTime `json:"completed_at"` CompletedAt sql.NullTime `json:"completed_at"`
HasTime bool `json:"has_time"` HasTime bool `json:"has_time"`
ShortID string `json:"short_id"`
} }
type TaskActivity struct { type TaskActivity struct {

View File

@ -12,7 +12,7 @@ import (
) )
const createPersonalProject = `-- name: CreatePersonalProject :one 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, public_on INSERT INTO project(team_id, created_at, name) VALUES (null, $1, $2) RETURNING project_id, team_id, created_at, name, public_on, short_id
` `
type CreatePersonalProjectParams struct { type CreatePersonalProjectParams struct {
@ -29,6 +29,7 @@ func (q *Queries) CreatePersonalProject(ctx context.Context, arg CreatePersonalP
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
) )
return i, err return i, err
} }
@ -80,7 +81,7 @@ func (q *Queries) CreateProjectMember(ctx context.Context, arg CreateProjectMemb
} }
const createTeamProject = `-- name: CreateTeamProject :one 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, public_on INSERT INTO project(team_id, created_at, name) VALUES ($1, $2, $3) RETURNING project_id, team_id, created_at, name, public_on, short_id
` `
type CreateTeamProjectParams struct { type CreateTeamProjectParams struct {
@ -98,6 +99,7 @@ func (q *Queries) CreateTeamProject(ctx context.Context, arg CreateTeamProjectPa
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
) )
return i, err return i, err
} }
@ -135,7 +137,7 @@ func (q *Queries) DeleteProjectMember(ctx context.Context, arg DeleteProjectMemb
} }
const getAllProjectsForTeam = `-- name: GetAllProjectsForTeam :many const getAllProjectsForTeam = `-- name: GetAllProjectsForTeam :many
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE team_id = $1 SELECT project_id, team_id, created_at, name, public_on, short_id FROM project WHERE team_id = $1
` `
func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error) { func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error) {
@ -153,6 +155,7 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -168,7 +171,7 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
} }
const getAllTeamProjects = `-- name: GetAllTeamProjects :many const getAllTeamProjects = `-- name: GetAllTeamProjects :many
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE team_id IS NOT null SELECT project_id, team_id, created_at, name, public_on, short_id FROM project WHERE team_id IS NOT null
` `
func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) { func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
@ -186,6 +189,7 @@ func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -201,7 +205,7 @@ func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
} }
const getAllVisibleProjectsForUserID = `-- name: GetAllVisibleProjectsForUserID :many const getAllVisibleProjectsForUserID = `-- name: GetAllVisibleProjectsForUserID :many
SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on FROM project LEFT JOIN SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on, project.short_id FROM project LEFT JOIN
project_member ON project_member.project_id = project.project_id WHERE project_member.user_id = $1 project_member ON project_member.project_id = project.project_id WHERE project_member.user_id = $1
` `
@ -220,6 +224,7 @@ func (q *Queries) GetAllVisibleProjectsForUserID(ctx context.Context, userID uui
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -298,7 +303,7 @@ func (q *Queries) GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.
} }
const getPersonalProjectsForUserID = `-- name: GetPersonalProjectsForUserID :many const getPersonalProjectsForUserID = `-- name: GetPersonalProjectsForUserID :many
SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on FROM project SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on, project.short_id FROM project
LEFT JOIN personal_project ON personal_project.project_id = project.project_id LEFT JOIN personal_project ON personal_project.project_id = project.project_id
WHERE personal_project.user_id = $1 WHERE personal_project.user_id = $1
` `
@ -318,6 +323,7 @@ func (q *Queries) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -333,7 +339,7 @@ func (q *Queries) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.
} }
const getProjectByID = `-- name: GetProjectByID :one const getProjectByID = `-- name: GetProjectByID :one
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE project_id = $1 SELECT project_id, team_id, created_at, name, public_on, short_id FROM project WHERE project_id = $1
` `
func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) { func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) {
@ -345,10 +351,22 @@ func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Proj
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
) )
return i, err return i, err
} }
const getProjectIDByShortID = `-- name: GetProjectIDByShortID :one
SELECT project_id FROM project WHERE short_id = $1
`
func (q *Queries) GetProjectIDByShortID(ctx context.Context, shortID string) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDByShortID, shortID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getProjectMemberInvitedIDByEmail = `-- name: GetProjectMemberInvitedIDByEmail :one const getProjectMemberInvitedIDByEmail = `-- name: GetProjectMemberInvitedIDByEmail :one
SELECT email, invited_on, project_member_invited_id FROM user_account_invited AS uai SELECT email, invited_on, project_member_invited_id FROM user_account_invited AS uai
inner join project_member_invited AS pmi inner join project_member_invited AS pmi
@ -489,7 +507,7 @@ func (q *Queries) GetUserRolesForProject(ctx context.Context, arg GetUserRolesFo
} }
const setPublicOn = `-- name: SetPublicOn :one 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 UPDATE project SET public_on = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on, short_id
` `
type SetPublicOnParams struct { type SetPublicOnParams struct {
@ -506,6 +524,7 @@ func (q *Queries) SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Proje
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
) )
return i, err return i, err
} }
@ -535,7 +554,7 @@ func (q *Queries) UpdateProjectMemberRole(ctx context.Context, arg UpdateProject
} }
const updateProjectNameByID = `-- name: UpdateProjectNameByID :one const updateProjectNameByID = `-- name: UpdateProjectNameByID :one
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on, short_id
` `
type UpdateProjectNameByIDParams struct { type UpdateProjectNameByIDParams struct {
@ -552,6 +571,7 @@ func (q *Queries) UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNa
&i.CreatedAt, &i.CreatedAt,
&i.Name, &i.Name,
&i.PublicOn, &i.PublicOn,
&i.ShortID,
) )
return i, err return i, err
} }

View File

@ -94,6 +94,7 @@ type Querier interface {
GetNotifiedByID(ctx context.Context, notifiedID uuid.UUID) (GetNotifiedByIDRow, error) GetNotifiedByID(ctx context.Context, notifiedID uuid.UUID) (GetNotifiedByIDRow, error)
GetPersonalProjectsForUserID(ctx context.Context, userID uuid.UUID) ([]Project, error) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.UUID) ([]Project, error)
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
GetProjectIDByShortID(ctx context.Context, shortID string) (uuid.UUID, error)
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error) GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error) GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error) GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error)
@ -119,6 +120,7 @@ type Querier interface {
GetTaskChecklistsForTask(ctx context.Context, taskID uuid.UUID) ([]TaskChecklist, error) GetTaskChecklistsForTask(ctx context.Context, taskID uuid.UUID) ([]TaskChecklist, error)
GetTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (TaskGroup, error) GetTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (TaskGroup, error)
GetTaskGroupsForProject(ctx context.Context, projectID uuid.UUID) ([]TaskGroup, error) GetTaskGroupsForProject(ctx context.Context, projectID uuid.UUID) ([]TaskGroup, error)
GetTaskIDByShortID(ctx context.Context, shortID string) (uuid.UUID, error)
GetTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) (TaskLabel, error) GetTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) (TaskLabel, error)
GetTaskLabelForTaskByProjectLabelID(ctx context.Context, arg GetTaskLabelForTaskByProjectLabelIDParams) (TaskLabel, error) GetTaskLabelForTaskByProjectLabelID(ctx context.Context, arg GetTaskLabelForTaskByProjectLabelIDParams) (TaskLabel, error)
GetTaskLabelsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskLabel, error) GetTaskLabelsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskLabel, error)

View File

@ -1,6 +1,9 @@
-- name: GetAllTeamProjects :many -- name: GetAllTeamProjects :many
SELECT * FROM project WHERE team_id IS NOT null; SELECT * FROM project WHERE team_id IS NOT null;
-- name: GetProjectIDByShortID :one
SELECT project_id FROM project WHERE short_id = $1;
-- name: GetAllProjectsForTeam :many -- name: GetAllProjectsForTeam :many
SELECT * FROM project WHERE team_id = $1; SELECT * FROM project WHERE team_id = $1;

View File

@ -4,6 +4,9 @@ SELECT * FROM task_watcher WHERE user_id = $1 AND task_id = $2;
-- name: CreateTaskWatcher :one -- name: CreateTaskWatcher :one
INSERT INTO task_watcher (user_id, task_id, watched_at) VALUES ($1, $2, $3) RETURNING *; INSERT INTO task_watcher (user_id, task_id, watched_at) VALUES ($1, $2, $3) RETURNING *;
-- name: GetTaskIDByShortID :one
SELECT task_id FROM task WHERE short_id = $1;
-- name: DeleteTaskWatcher :exec -- name: DeleteTaskWatcher :exec
DELETE FROM task_watcher WHERE user_id = $1 AND task_id = $2; DELETE FROM task_watcher WHERE user_id = $1 AND task_id = $2;
@ -54,7 +57,7 @@ SELECT project_id FROM task
WHERE task_id = $1; WHERE task_id = $1;
-- name: GetProjectInfoForTask :one -- name: GetProjectInfoForTask :one
SELECT project.project_id, project.name FROM task SELECT project.short_id AS project_short_id, project.name, task.short_id AS task_short_id FROM task
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
INNER JOIN project ON task_group.project_id = project.project_id INNER JOIN project ON task_group.project_id = project.project_id
WHERE task_id = $1; WHERE task_id = $1;

View File

@ -14,7 +14,7 @@ import (
const createTask = `-- name: CreateTask :one const createTask = `-- name: CreateTask :one
INSERT INTO task (task_group_id, created_at, name, position) INSERT INTO task (task_group_id, created_at, name, position)
VALUES($1, $2, $3, $4) RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time VALUES($1, $2, $3, $4) RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type CreateTaskParams struct { type CreateTaskParams struct {
@ -43,13 +43,14 @@ func (q *Queries) CreateTask(ctx context.Context, arg CreateTaskParams) (Task, e
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
const createTaskAll = `-- name: CreateTaskAll :one const createTaskAll = `-- name: CreateTaskAll :one
INSERT INTO task (task_group_id, created_at, name, position, description, complete, due_date) INSERT INTO task (task_group_id, created_at, name, position, description, complete, due_date)
VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type CreateTaskAllParams struct { type CreateTaskAllParams struct {
@ -84,6 +85,7 @@ func (q *Queries) CreateTaskAll(ctx context.Context, arg CreateTaskAllParams) (T
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
@ -197,7 +199,7 @@ func (q *Queries) DeleteTasksByTaskGroupID(ctx context.Context, taskGroupID uuid
} }
const getAllTasks = `-- name: GetAllTasks :many const getAllTasks = `-- name: GetAllTasks :many
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time FROM task SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id FROM task
` `
func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) { func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) {
@ -220,6 +222,7 @@ func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) {
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -235,7 +238,7 @@ func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) {
} }
const getAssignedTasksDueDateForUserID = `-- name: GetAssignedTasksDueDateForUserID :many const getAssignedTasksDueDateForUserID = `-- name: GetAssignedTasksDueDateForUserID :many
SELECT task.task_id, task.task_group_id, task.created_at, task.name, task.position, task.description, task.due_date, task.complete, task.completed_at, task.has_time FROM task_assigned SELECT task.task_id, task.task_group_id, task.created_at, task.name, task.position, task.description, task.due_date, task.complete, task.completed_at, task.has_time, task.short_id FROM task_assigned
INNER JOIN task ON task.task_id = task_assigned.task_id INNER JOIN task ON task.task_id = task_assigned.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE user_id = $1 WHERE user_id = $1
@ -279,6 +282,7 @@ func (q *Queries) GetAssignedTasksDueDateForUserID(ctx context.Context, arg GetA
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -294,7 +298,7 @@ func (q *Queries) GetAssignedTasksDueDateForUserID(ctx context.Context, arg GetA
} }
const getAssignedTasksProjectForUserID = `-- name: GetAssignedTasksProjectForUserID :many const getAssignedTasksProjectForUserID = `-- name: GetAssignedTasksProjectForUserID :many
SELECT task.task_id, task.task_group_id, task.created_at, task.name, task.position, task.description, task.due_date, task.complete, task.completed_at, task.has_time FROM task_assigned SELECT task.task_id, task.task_group_id, task.created_at, task.name, task.position, task.description, task.due_date, task.complete, task.completed_at, task.has_time, task.short_id FROM task_assigned
INNER JOIN task ON task.task_id = task_assigned.task_id INNER JOIN task ON task.task_id = task_assigned.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE user_id = $1 WHERE user_id = $1
@ -338,6 +342,7 @@ func (q *Queries) GetAssignedTasksProjectForUserID(ctx context.Context, arg GetA
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -446,26 +451,27 @@ func (q *Queries) GetProjectIdMappings(ctx context.Context, dollar_1 []uuid.UUID
} }
const getProjectInfoForTask = `-- name: GetProjectInfoForTask :one const getProjectInfoForTask = `-- name: GetProjectInfoForTask :one
SELECT project.project_id, project.name FROM task SELECT project.short_id AS project_short_id, project.name, task.short_id AS task_short_id FROM task
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
INNER JOIN project ON task_group.project_id = project.project_id INNER JOIN project ON task_group.project_id = project.project_id
WHERE task_id = $1 WHERE task_id = $1
` `
type GetProjectInfoForTaskRow struct { type GetProjectInfoForTaskRow struct {
ProjectID uuid.UUID `json:"project_id"` ProjectShortID string `json:"project_short_id"`
Name string `json:"name"` Name string `json:"name"`
TaskShortID string `json:"task_short_id"`
} }
func (q *Queries) GetProjectInfoForTask(ctx context.Context, taskID uuid.UUID) (GetProjectInfoForTaskRow, error) { func (q *Queries) GetProjectInfoForTask(ctx context.Context, taskID uuid.UUID) (GetProjectInfoForTaskRow, error) {
row := q.db.QueryRowContext(ctx, getProjectInfoForTask, taskID) row := q.db.QueryRowContext(ctx, getProjectInfoForTask, taskID)
var i GetProjectInfoForTaskRow var i GetProjectInfoForTaskRow
err := row.Scan(&i.ProjectID, &i.Name) err := row.Scan(&i.ProjectShortID, &i.Name, &i.TaskShortID)
return i, err return i, err
} }
const getRecentlyAssignedTaskForUserID = `-- name: GetRecentlyAssignedTaskForUserID :many const getRecentlyAssignedTaskForUserID = `-- name: GetRecentlyAssignedTaskForUserID :many
SELECT task.task_id, task.task_group_id, task.created_at, task.name, task.position, task.description, task.due_date, task.complete, task.completed_at, task.has_time FROM task_assigned INNER JOIN SELECT task.task_id, task.task_group_id, task.created_at, task.name, task.position, task.description, task.due_date, task.complete, task.completed_at, task.has_time, task.short_id FROM task_assigned INNER JOIN
task ON task.task_id = task_assigned.task_id WHERE user_id = $1 task ON task.task_id = task_assigned.task_id WHERE user_id = $1
AND $4::boolean = true OR ( AND $4::boolean = true OR (
$4::boolean = false AND complete = $2 AND ( $4::boolean = false AND complete = $2 AND (
@ -507,6 +513,7 @@ func (q *Queries) GetRecentlyAssignedTaskForUserID(ctx context.Context, arg GetR
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -522,7 +529,7 @@ func (q *Queries) GetRecentlyAssignedTaskForUserID(ctx context.Context, arg GetR
} }
const getTaskByID = `-- name: GetTaskByID :one const getTaskByID = `-- name: GetTaskByID :one
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time FROM task WHERE task_id = $1 SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id FROM task WHERE task_id = $1
` `
func (q *Queries) GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error) { func (q *Queries) GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error) {
@ -539,10 +546,22 @@ func (q *Queries) GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, erro
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
const getTaskIDByShortID = `-- name: GetTaskIDByShortID :one
SELECT task_id FROM task WHERE short_id = $1
`
func (q *Queries) GetTaskIDByShortID(ctx context.Context, shortID string) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getTaskIDByShortID, shortID)
var task_id uuid.UUID
err := row.Scan(&task_id)
return task_id, err
}
const getTaskWatcher = `-- name: GetTaskWatcher :one const getTaskWatcher = `-- name: GetTaskWatcher :one
SELECT task_watcher_id, task_id, user_id, watched_at FROM task_watcher WHERE user_id = $1 AND task_id = $2 SELECT task_watcher_id, task_id, user_id, watched_at FROM task_watcher WHERE user_id = $1 AND task_id = $2
` `
@ -565,7 +584,7 @@ func (q *Queries) GetTaskWatcher(ctx context.Context, arg GetTaskWatcherParams)
} }
const getTasksForTaskGroupID = `-- name: GetTasksForTaskGroupID :many const getTasksForTaskGroupID = `-- name: GetTasksForTaskGroupID :many
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time FROM task WHERE task_group_id = $1 SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id FROM task WHERE task_group_id = $1
` `
func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error) { func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error) {
@ -588,6 +607,7 @@ func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.U
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -603,7 +623,7 @@ func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.U
} }
const setTaskComplete = `-- name: SetTaskComplete :one const setTaskComplete = `-- name: SetTaskComplete :one
UPDATE task SET complete = $2, completed_at = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time UPDATE task SET complete = $2, completed_at = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type SetTaskCompleteParams struct { type SetTaskCompleteParams struct {
@ -626,6 +646,7 @@ func (q *Queries) SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
@ -656,7 +677,7 @@ func (q *Queries) UpdateTaskComment(ctx context.Context, arg UpdateTaskCommentPa
} }
const updateTaskDescription = `-- name: UpdateTaskDescription :one const updateTaskDescription = `-- name: UpdateTaskDescription :one
UPDATE task SET description = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time UPDATE task SET description = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type UpdateTaskDescriptionParams struct { type UpdateTaskDescriptionParams struct {
@ -678,12 +699,13 @@ func (q *Queries) UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescr
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
const updateTaskDueDate = `-- name: UpdateTaskDueDate :one const updateTaskDueDate = `-- name: UpdateTaskDueDate :one
UPDATE task SET due_date = $2, has_time = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time UPDATE task SET due_date = $2, has_time = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type UpdateTaskDueDateParams struct { type UpdateTaskDueDateParams struct {
@ -706,12 +728,13 @@ func (q *Queries) UpdateTaskDueDate(ctx context.Context, arg UpdateTaskDueDatePa
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
const updateTaskLocation = `-- name: UpdateTaskLocation :one const updateTaskLocation = `-- name: UpdateTaskLocation :one
UPDATE task SET task_group_id = $2, position = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time UPDATE task SET task_group_id = $2, position = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type UpdateTaskLocationParams struct { type UpdateTaskLocationParams struct {
@ -734,12 +757,13 @@ func (q *Queries) UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocation
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
const updateTaskName = `-- name: UpdateTaskName :one const updateTaskName = `-- name: UpdateTaskName :one
UPDATE task SET name = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time UPDATE task SET name = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type UpdateTaskNameParams struct { type UpdateTaskNameParams struct {
@ -761,12 +785,13 @@ func (q *Queries) UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams)
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }
const updateTaskPosition = `-- name: UpdateTaskPosition :one const updateTaskPosition = `-- name: UpdateTaskPosition :one
UPDATE task SET position = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time UPDATE task SET position = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at, has_time, short_id
` `
type UpdateTaskPositionParams struct { type UpdateTaskPositionParams struct {
@ -788,6 +813,7 @@ func (q *Queries) UpdateTaskPosition(ctx context.Context, arg UpdateTaskPosition
&i.Complete, &i.Complete,
&i.CompletedAt, &i.CompletedAt,
&i.HasTime, &i.HasTime,
&i.ShortID,
) )
return i, err return i, err
} }

View File

@ -359,6 +359,7 @@ type ComplexityRoot struct {
Name func(childComplexity int) int Name func(childComplexity int) int
Permission func(childComplexity int) int Permission func(childComplexity int) int
PublicOn func(childComplexity int) int PublicOn func(childComplexity int) int
ShortID func(childComplexity int) int
TaskGroups func(childComplexity int) int TaskGroups func(childComplexity int) int
Team func(childComplexity int) int Team func(childComplexity int) int
} }
@ -436,6 +437,7 @@ type ComplexityRoot struct {
Labels func(childComplexity int) int Labels func(childComplexity int) int
Name func(childComplexity int) int Name func(childComplexity int) int
Position func(childComplexity int) int Position func(childComplexity int) int
ShortID func(childComplexity int) int
TaskGroup func(childComplexity int) int TaskGroup func(childComplexity int) int
Watched func(childComplexity int) int Watched func(childComplexity int) int
} }
@ -680,11 +682,9 @@ type QueryResolver interface {
Users(ctx context.Context) ([]db.UserAccount, error) Users(ctx context.Context) ([]db.UserAccount, error)
InvitedUsers(ctx context.Context) ([]InvitedUserAccount, error) InvitedUsers(ctx context.Context) ([]InvitedUserAccount, error)
FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error) FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error)
FindProject(ctx context.Context, input FindProject) (*db.Project, error)
FindTask(ctx context.Context, input FindTask) (*db.Task, error)
Projects(ctx context.Context, input *ProjectsFilter) ([]db.Project, error) Projects(ctx context.Context, input *ProjectsFilter) ([]db.Project, error)
FindTeam(ctx context.Context, input FindTeam) (*db.Team, error)
Teams(ctx context.Context) ([]db.Team, error) Teams(ctx context.Context) ([]db.Team, error)
FindTeam(ctx context.Context, input FindTeam) (*db.Team, error)
MyTasks(ctx context.Context, input MyTasks) (*MyTasksPayload, error) MyTasks(ctx context.Context, input MyTasks) (*MyTasksPayload, error)
LabelColors(ctx context.Context) ([]db.LabelColor, error) LabelColors(ctx context.Context) ([]db.LabelColor, error)
TaskGroups(ctx context.Context) ([]db.TaskGroup, error) TaskGroups(ctx context.Context) ([]db.TaskGroup, error)
@ -692,6 +692,8 @@ type QueryResolver interface {
Notifications(ctx context.Context) ([]Notified, error) Notifications(ctx context.Context) ([]Notified, error)
Notified(ctx context.Context, input NotifiedInput) (*NotifiedResult, error) Notified(ctx context.Context, input NotifiedInput) (*NotifiedResult, error)
HasUnreadNotifications(ctx context.Context) (*HasUnreadNotificationsResult, error) HasUnreadNotifications(ctx context.Context) (*HasUnreadNotificationsResult, error)
FindProject(ctx context.Context, input FindProject) (*db.Project, error)
FindTask(ctx context.Context, input FindTask) (*db.Task, error)
SearchMembers(ctx context.Context, input MemberSearchFilter) ([]MemberSearchResult, error) SearchMembers(ctx context.Context, input MemberSearchFilter) ([]MemberSearchResult, error)
} }
type SubscriptionResolver interface { type SubscriptionResolver interface {
@ -699,6 +701,7 @@ type SubscriptionResolver interface {
} }
type TaskResolver interface { type TaskResolver interface {
ID(ctx context.Context, obj *db.Task) (uuid.UUID, error) ID(ctx context.Context, obj *db.Task) (uuid.UUID, error)
TaskGroup(ctx context.Context, obj *db.Task) (*db.TaskGroup, error) TaskGroup(ctx context.Context, obj *db.Task) (*db.TaskGroup, error)
Description(ctx context.Context, obj *db.Task) (*string, error) Description(ctx context.Context, obj *db.Task) (*string, error)
@ -2264,6 +2267,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Project.PublicOn(childComplexity), true return e.complexity.Project.PublicOn(childComplexity), true
case "Project.shortId":
if e.complexity.Project.ShortID == nil {
break
}
return e.complexity.Project.ShortID(childComplexity), true
case "Project.taskGroups": case "Project.taskGroups":
if e.complexity.Project.TaskGroups == nil { if e.complexity.Project.TaskGroups == nil {
break break
@ -2654,6 +2664,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Task.Position(childComplexity), true return e.complexity.Task.Position(childComplexity), true
case "Task.shortId":
if e.complexity.Task.ShortID == nil {
break
}
return e.complexity.Task.ShortID(childComplexity), true
case "Task.taskGroup": case "Task.taskGroup":
if e.complexity.Task.TaskGroup == nil { if e.complexity.Task.TaskGroup == nil {
break break
@ -3364,6 +3381,7 @@ type Notified {
type Project { type Project {
id: ID! id: ID!
shortId: String!
createdAt: Time! createdAt: Time!
name: String! name: String!
team: Team team: Team
@ -3503,6 +3521,15 @@ type UpdateProjectMemberRolePayload {
member: Member! member: Member!
} }
extend type Query {
findProject(input: FindProject!): Project!
}
input FindProject {
projectID: UUID
projectShortID: String
}
extend type Mutation { extend type Mutation {
createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
deleteProject(input: DeleteProject!): deleteProject(input: DeleteProject!):
@ -3618,12 +3645,9 @@ type Query {
users: [UserAccount!]! users: [UserAccount!]!
invitedUsers: [InvitedUserAccount!]! invitedUsers: [InvitedUserAccount!]!
findUser(input: FindUser!): UserAccount! findUser(input: FindUser!): UserAccount!
findProject(input: FindProject!):
Project!
findTask(input: FindTask!): Task!
projects(input: ProjectsFilter): [Project!]! projects(input: ProjectsFilter): [Project!]!
findTeam(input: FindTeam!): Team!
teams: [Team!]! teams: [Team!]!
findTeam(input: FindTeam!): Team!
myTasks(input: MyTasks!): MyTasksPayload! myTasks(input: MyTasks!): MyTasksPayload!
labelColors: [LabelColor!]! labelColors: [LabelColor!]!
taskGroups: [TaskGroup!]! taskGroups: [TaskGroup!]!
@ -3691,13 +3715,6 @@ input FindUser {
userID: UUID! userID: UUID!
} }
input FindProject {
projectID: UUID!
}
input FindTask {
taskID: UUID!
}
input FindTeam { input FindTeam {
teamID: UUID! teamID: UUID!
@ -3727,6 +3744,7 @@ type TaskBadges {
type Task { type Task {
id: ID! id: ID!
shortId: String!
taskGroup: TaskGroup! taskGroup: TaskGroup!
createdAt: Time! createdAt: Time!
name: String! name: String!
@ -4042,6 +4060,16 @@ type ToggleTaskLabelPayload {
task: Task! task: Task!
} }
extend type Query {
findTask(input: FindTask!): Task!
}
input FindTask {
taskID: UUID
taskShortID: String
}
extend type Mutation { extend type Mutation {
createTask(input: NewTask!): createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
@ -13300,6 +13328,41 @@ func (ec *executionContext) _Project_id(ctx context.Context, field graphql.Colle
return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res) return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res)
} }
func (ec *executionContext) _Project_shortId(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: 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.ShortID, 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.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _Project_createdAt(ctx context.Context, field graphql.CollectedField, obj *db.Project) (ret graphql.Marshaler) { func (ec *executionContext) _Project_createdAt(ctx context.Context, field graphql.CollectedField, obj *db.Project) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -14138,90 +14201,6 @@ func (ec *executionContext) _Query_findUser(ctx context.Context, field graphql.C
return ec.marshalNUserAccount2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐUserAccount(ctx, field.Selections, res) return ec.marshalNUserAccount2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐUserAccount(ctx, field.Selections, res)
} }
func (ec *executionContext) _Query_findProject(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: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_findProject_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) {
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)
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) _Query_findTask(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: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_findTask_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) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().FindTask(rctx, args["input"].(FindTask))
})
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.Task)
fc.Result = res
return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐTask(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_projects(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query_projects(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -14264,6 +14243,41 @@ func (ec *executionContext) _Query_projects(ctx context.Context, field graphql.C
return ec.marshalNProject2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐProjectᚄ(ctx, field.Selections, res) return ec.marshalNProject2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐProjectᚄ(ctx, field.Selections, res)
} }
func (ec *executionContext) _Query_teams(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: "Query",
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.Query().Teams(rctx)
})
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.Team)
fc.Result = res
return ec.marshalNTeam2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐTeamᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_findTeam(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query_findTeam(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -14306,41 +14320,6 @@ func (ec *executionContext) _Query_findTeam(ctx context.Context, field graphql.C
return ec.marshalNTeam2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐTeam(ctx, field.Selections, res) return ec.marshalNTeam2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐTeam(ctx, field.Selections, res)
} }
func (ec *executionContext) _Query_teams(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: "Query",
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.Query().Teams(rctx)
})
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.Team)
fc.Result = res
return ec.marshalNTeam2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐTeamᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_myTasks(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query_myTasks(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -14597,6 +14576,90 @@ func (ec *executionContext) _Query_hasUnreadNotifications(ctx context.Context, f
return ec.marshalNHasUnreadNotificationsResult2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐHasUnreadNotificationsResult(ctx, field.Selections, res) return ec.marshalNHasUnreadNotificationsResult2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐHasUnreadNotificationsResult(ctx, field.Selections, res)
} }
func (ec *executionContext) _Query_findProject(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: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_findProject_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) {
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)
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) _Query_findTask(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: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_findTask_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) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().FindTask(rctx, args["input"].(FindTask))
})
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.Task)
fc.Result = res
return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐTask(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_searchMembers(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query_searchMembers(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -14930,6 +14993,41 @@ func (ec *executionContext) _Task_id(ctx context.Context, field graphql.Collecte
return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res) return ec.marshalNID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, field.Selections, res)
} }
func (ec *executionContext) _Task_shortId(ctx context.Context, field graphql.CollectedField, obj *db.Task) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Task",
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.ShortID, 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.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _Task_taskGroup(ctx context.Context, field graphql.CollectedField, obj *db.Task) (ret graphql.Marshaler) { func (ec *executionContext) _Task_taskGroup(ctx context.Context, field graphql.CollectedField, obj *db.Task) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -19707,7 +19805,15 @@ func (ec *executionContext) unmarshalInputFindProject(ctx context.Context, obj i
var err error var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("projectID")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("projectID"))
it.ProjectID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v) it.ProjectID, err = ec.unmarshalOUUID2ᚖgithubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
case "projectShortID":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("projectShortID"))
it.ProjectShortID, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil { if err != nil {
return it, err return it, err
} }
@ -19727,7 +19833,15 @@ func (ec *executionContext) unmarshalInputFindTask(ctx context.Context, obj inte
var err error var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("taskID")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("taskID"))
it.TaskID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v) it.TaskID, err = ec.unmarshalOUUID2ᚖgithubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
case "taskShortID":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("taskShortID"))
it.TaskShortID, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil { if err != nil {
return it, err return it, err
} }
@ -22875,6 +22989,11 @@ func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet,
} }
return res return res
}) })
case "shortId":
out.Values[i] = ec._Project_shortId(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "createdAt": case "createdAt":
out.Values[i] = ec._Project_createdAt(ctx, field, obj) out.Values[i] = ec._Project_createdAt(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@ -23226,34 +23345,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
} }
return res return res
}) })
case "findProject":
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._Query_findProject(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "findTask":
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._Query_findTask(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "projects": case "projects":
field := field field := field
out.Concurrently(i, func() (res graphql.Marshaler) { out.Concurrently(i, func() (res graphql.Marshaler) {
@ -23268,20 +23359,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
} }
return res return res
}) })
case "findTeam":
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._Query_findTeam(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "teams": case "teams":
field := field field := field
out.Concurrently(i, func() (res graphql.Marshaler) { out.Concurrently(i, func() (res graphql.Marshaler) {
@ -23296,6 +23373,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
} }
return res return res
}) })
case "findTeam":
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._Query_findTeam(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "myTasks": case "myTasks":
field := field field := field
out.Concurrently(i, func() (res graphql.Marshaler) { out.Concurrently(i, func() (res graphql.Marshaler) {
@ -23391,6 +23482,34 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
} }
return res return res
}) })
case "findProject":
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._Query_findProject(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "findTask":
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._Query_findTask(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "searchMembers": case "searchMembers":
field := field field := field
out.Concurrently(i, func() (res graphql.Marshaler) { out.Concurrently(i, func() (res graphql.Marshaler) {
@ -23529,6 +23648,11 @@ func (ec *executionContext) _Task(ctx context.Context, sel ast.SelectionSet, obj
} }
return res return res
}) })
case "shortId":
out.Values[i] = ec._Task_shortId(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "taskGroup": case "taskGroup":
field := field field := field
out.Concurrently(i, func() (res graphql.Marshaler) { out.Concurrently(i, func() (res graphql.Marshaler) {

View File

@ -215,11 +215,13 @@ type DuplicateTaskGroupPayload struct {
} }
type FindProject struct { type FindProject struct {
ProjectID uuid.UUID `json:"projectID"` ProjectID *uuid.UUID `json:"projectID"`
ProjectShortID *string `json:"projectShortID"`
} }
type FindTask struct { type FindTask struct {
TaskID uuid.UUID `json:"taskID"` TaskID *uuid.UUID `json:"taskID"`
TaskShortID *string `json:"taskShortID"`
} }
type FindTeam struct { type FindTeam struct {

View File

@ -392,6 +392,39 @@ func (r *projectLabelResolver) Name(ctx context.Context, obj *db.ProjectLabel) (
return name, nil return name, nil
} }
func (r *queryResolver) FindProject(ctx context.Context, input FindProject) (*db.Project, error) {
_, isLoggedIn := GetUser(ctx)
var projectID uuid.UUID
var err error
if input.ProjectID != nil {
projectID = *input.ProjectID
} else if input.ProjectShortID != nil {
projectID, err = r.Repository.GetProjectIDByShortID(ctx, *input.ProjectShortID)
if err != nil {
log.WithError(err).Error("error while getting project id by short id")
return &db.Project{}, err
}
} else {
return &db.Project{}, errors.New("FindProject requires either ProjectID or ProjectShortID to be set")
}
if !isLoggedIn {
isPublic, _ := IsProjectPublic(ctx, r.Repository, projectID)
if !isPublic {
return &db.Project{}, NotAuthorized()
}
}
project, err := r.Repository.GetProjectByID(ctx, projectID)
if err == sql.ErrNoRows {
return &db.Project{}, &gqlerror.Error{
Message: "Project not found",
Extensions: map[string]interface{}{
"code": "NOT_FOUND",
},
}
}
return &project, nil
}
// LabelColor returns LabelColorResolver implementation. // LabelColor returns LabelColorResolver implementation.
func (r *Resolver) LabelColor() LabelColorResolver { return &labelColorResolver{r} } func (r *Resolver) LabelColor() LabelColorResolver { return &labelColorResolver{r} }

View File

@ -61,31 +61,6 @@ func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserA
return &account, err return &account, err
} }
func (r *queryResolver) FindProject(ctx context.Context, input FindProject) (*db.Project, error) {
_, 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": "NOT_FOUND",
},
}
}
return &project, nil
}
func (r *queryResolver) FindTask(ctx context.Context, input FindTask) (*db.Task, error) {
task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
return &task, err
}
func (r *queryResolver) Projects(ctx context.Context, input *ProjectsFilter) ([]db.Project, error) { func (r *queryResolver) Projects(ctx context.Context, input *ProjectsFilter) ([]db.Project, error) {
userID, ok := GetUser(ctx) userID, ok := GetUser(ctx)
if !ok { if !ok {
@ -137,14 +112,6 @@ func (r *queryResolver) Projects(ctx context.Context, input *ProjectsFilter) ([]
return allProjects, nil return allProjects, nil
} }
func (r *queryResolver) FindTeam(ctx context.Context, input FindTeam) (*db.Team, error) {
team, err := r.Repository.GetTeamByID(ctx, input.TeamID)
if err != nil {
return &db.Team{}, err
}
return &team, nil
}
func (r *queryResolver) Teams(ctx context.Context) ([]db.Team, error) { func (r *queryResolver) Teams(ctx context.Context) ([]db.Team, error) {
userID, ok := GetUser(ctx) userID, ok := GetUser(ctx)
if !ok { if !ok {
@ -190,6 +157,14 @@ func (r *queryResolver) Teams(ctx context.Context) ([]db.Team, error) {
return foundTeams, nil return foundTeams, nil
} }
func (r *queryResolver) FindTeam(ctx context.Context, input FindTeam) (*db.Team, error) {
team, err := r.Repository.GetTeamByID(ctx, input.TeamID)
if err != nil {
return &db.Team{}, err
}
return &team, nil
}
func (r *queryResolver) MyTasks(ctx context.Context, input MyTasks) (*MyTasksPayload, error) { func (r *queryResolver) MyTasks(ctx context.Context, input MyTasks) (*MyTasksPayload, error) {
userID, _ := GetUserID(ctx) userID, _ := GetUserID(ctx)
projects := []ProjectTaskMapping{} projects := []ProjectTaskMapping{}

View File

@ -6,6 +6,7 @@ type ProjectPermission {
type Project { type Project {
id: ID! id: ID!
shortId: String!
createdAt: Time! createdAt: Time!
name: String! name: String!
team: Team team: Team
@ -145,6 +146,15 @@ type UpdateProjectMemberRolePayload {
member: Member! member: Member!
} }
extend type Query {
findProject(input: FindProject!): Project!
}
input FindProject {
projectID: UUID
projectShortID: String
}
extend type Mutation { extend type Mutation {
createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
deleteProject(input: DeleteProject!): deleteProject(input: DeleteProject!):

View File

@ -6,6 +6,7 @@ type ProjectPermission {
type Project { type Project {
id: ID! id: ID!
shortId: String!
createdAt: Time! createdAt: Time!
name: String! name: String!
team: Team team: Team

View File

@ -1,3 +1,12 @@
extend type Query {
findProject(input: FindProject!): Project!
}
input FindProject {
projectID: UUID
projectShortID: String
}
extend type Mutation { extend type Mutation {
createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
deleteProject(input: DeleteProject!): deleteProject(input: DeleteProject!):

View File

@ -75,12 +75,9 @@ type Query {
users: [UserAccount!]! users: [UserAccount!]!
invitedUsers: [InvitedUserAccount!]! invitedUsers: [InvitedUserAccount!]!
findUser(input: FindUser!): UserAccount! findUser(input: FindUser!): UserAccount!
findProject(input: FindProject!):
Project!
findTask(input: FindTask!): Task!
projects(input: ProjectsFilter): [Project!]! projects(input: ProjectsFilter): [Project!]!
findTeam(input: FindTeam!): Team!
teams: [Team!]! teams: [Team!]!
findTeam(input: FindTeam!): Team!
myTasks(input: MyTasks!): MyTasksPayload! myTasks(input: MyTasks!): MyTasksPayload!
labelColors: [LabelColor!]! labelColors: [LabelColor!]!
taskGroups: [TaskGroup!]! taskGroups: [TaskGroup!]!
@ -148,13 +145,6 @@ input FindUser {
userID: UUID! userID: UUID!
} }
input FindProject {
projectID: UUID!
}
input FindTask {
taskID: UUID!
}
input FindTeam { input FindTeam {
teamID: UUID! teamID: UUID!

View File

@ -22,6 +22,7 @@ type TaskBadges {
type Task { type Task {
id: ID! id: ID!
shortId: String!
taskGroup: TaskGroup! taskGroup: TaskGroup!
createdAt: Time! createdAt: Time!
name: String! name: String!
@ -337,6 +338,16 @@ type ToggleTaskLabelPayload {
task: Task! task: Task!
} }
extend type Query {
findTask(input: FindTask!): Task!
}
input FindTask {
taskID: UUID
taskShortID: String
}
extend type Mutation { extend type Mutation {
createTask(input: NewTask!): createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)

View File

@ -22,6 +22,7 @@ type TaskBadges {
type Task { type Task {
id: ID! id: ID!
shortId: String!
taskGroup: TaskGroup! taskGroup: TaskGroup!
createdAt: Time! createdAt: Time!
name: String! name: String!

View File

@ -1,3 +1,13 @@
extend type Query {
findTask(input: FindTask!): Task!
}
input FindTask {
taskID: UUID
taskShortID: String
}
extend type Mutation { extend type Mutation {
createTask(input: NewTask!): createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)

View File

@ -635,9 +635,9 @@ func (r *mutationResolver) AssignTask(ctx context.Context, input *AssignTaskInpu
Data: map[string]string{ Data: map[string]string{
"CausedByUsername": causedBy.Username, "CausedByUsername": causedBy.Username,
"CausedByFullName": causedBy.FullName, "CausedByFullName": causedBy.FullName,
"TaskID": assignedTask.TaskID.String(), "TaskID": project.TaskShortID,
"TaskName": task.Name, "TaskName": task.Name,
"ProjectID": project.ProjectID.String(), "ProjectID": project.ProjectShortID,
"ProjectName": project.Name, "ProjectName": project.Name,
}, },
}) })
@ -670,6 +670,23 @@ func (r *mutationResolver) UnassignTask(ctx context.Context, input *UnassignTask
return &task, nil return &task, nil
} }
func (r *queryResolver) FindTask(ctx context.Context, input FindTask) (*db.Task, error) {
var taskID uuid.UUID
var err error
if input.TaskID != nil {
taskID = *input.TaskID
} else if input.TaskShortID != nil {
taskID, err = r.Repository.GetTaskIDByShortID(ctx, *input.TaskShortID)
if err != nil {
return &db.Task{}, err
}
} else {
return &db.Task{}, errors.New("FindTask requires either TaskID or TaskShortID to be set")
}
task, err := r.Repository.GetTaskByID(ctx, taskID)
return &task, err
}
func (r *taskResolver) ID(ctx context.Context, obj *db.Task) (uuid.UUID, error) { func (r *taskResolver) ID(ctx context.Context, obj *db.Task) (uuid.UUID, error) {
return obj.TaskID, nil return obj.TaskID, nil
} }

View File

@ -0,0 +1,68 @@
CREATE OR REPLACE FUNCTION unique_short_id()
RETURNS TRIGGER AS $$
-- Declare the variables we'll be using.
DECLARE
key TEXT;
qry TEXT;
found TEXT;
BEGIN
-- generate the first part of a query as a string with safely
-- escaped table name, using || to concat the parts
qry := 'SELECT short_id FROM ' || quote_ident(TG_TABLE_NAME) || ' WHERE short_id=';
-- This loop will probably only run once per call until we've generated
-- millions of ids.
LOOP
-- Generate our string bytes and re-encode as a base64 string.
key := encode(gen_random_bytes(6), 'base64');
-- Base64 encoding contains 2 URL unsafe characters by default.
-- The URL-safe version has these replacements.
key := replace(key, '/', '_'); -- url safe replacement
key := replace(key, '+', '-'); -- url safe replacement
-- Concat the generated key (safely quoted) with the generated query
-- and run it.
-- SELECT id FROM "test" WHERE id='blahblah' INTO found
-- Now "found" will be the duplicated id or NULL.
EXECUTE qry || quote_literal(key) INTO found;
-- Check to see if found is NULL.
-- If we checked to see if found = NULL it would always be FALSE
-- because (NULL = NULL) is always FALSE.
IF found IS NULL THEN
-- If we didn't find a collision then leave the LOOP.
EXIT;
END IF;
-- We haven't EXITed yet, so return to the top of the LOOP
-- and try again.
END LOOP;
-- NEW and OLD are available in TRIGGER PROCEDURES.
-- NEW is the mutated row that will actually be INSERTed.
-- We're replacing id, regardless of what it was before
-- with our key variable.
NEW.short_id = key;
-- The RECORD returned here is what will actually be INSERTed,
-- or what the next trigger will get if there is one.
RETURN NEW;
END;
$$ language 'plpgsql';
ALTER TABLE project ADD COLUMN short_id text UNIQUE;
UPDATE project SET short_id = encode(gen_random_bytes(6), 'base64');
ALTER TABLE project ALTER COLUMN short_id SET NOT NULL;
ALTER TABLE project ADD CONSTRAINT project_short_id_unique UNIQUE (short_id);
CREATE TRIGGER trigger_project_short_id BEFORE INSERT ON project FOR EACH ROW EXECUTE PROCEDURE unique_short_id();
ALTER TABLE task ADD COLUMN short_id text UNIQUE;
UPDATE task SET short_id = encode(gen_random_bytes(6), 'base64');
ALTER TABLE task ALTER COLUMN short_id SET NOT NULL;
ALTER TABLE task ADD CONSTRAINT task_short_id_unique UNIQUE (short_id);
CREATE TRIGGER trigger_task_short_id BEFORE INSERT ON task FOR EACH ROW EXECUTE PROCEDURE unique_short_id();