Add ability to change project's color
This commit is contained in:
parent
d7ee9e50e6
commit
fb0260466a
6 changed files with 117 additions and 1 deletions
|
@ -0,0 +1,18 @@
|
|||
module Twenty::GraphQL::Mutation
|
||||
class SetRandomProjectColor < ::GraphQL::Schema::Mutation
|
||||
require_relative "../type/project"
|
||||
argument :project_id, Int, required: true
|
||||
field :ok, Boolean, null: false
|
||||
field :errors, [String], null: false
|
||||
field :project, Twenty::GraphQL::Type::Project, null: true
|
||||
|
||||
def resolve(project_id:)
|
||||
project = Twenty::Project.find_by(id: project_id)
|
||||
project.color = project.send(:random_color)
|
||||
project.save!
|
||||
{ok: true, errors: [], project:}
|
||||
rescue => ex
|
||||
{ok: false, errors: [ex.message]}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,9 +4,11 @@ module Twenty::GraphQL::Type
|
|||
require_relative "../mutation/complete_task"
|
||||
require_relative "../mutation/create_task"
|
||||
require_relative "../mutation/update_task"
|
||||
require_relative "../mutation/set_random_project_color"
|
||||
field :destroy_task, mutation: Twenty::GraphQL::Mutation::DestroyTask
|
||||
field :complete_task, mutation: Twenty::GraphQL::Mutation::CompleteTask
|
||||
field :create_task, mutation: Twenty::GraphQL::Mutation::CreateTask
|
||||
field :update_task, mutation: Twenty::GraphQL::Mutation::UpdateTask
|
||||
field :set_random_project_color, mutation: Twenty::GraphQL::Mutation::SetRandomProjectColor
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@ type Mutation {
|
|||
completeTask(taskId: Int!): CompleteTaskPayload
|
||||
createTask(input: TaskInput!): CreateTaskPayload
|
||||
destroyTask(taskId: Int!): DestroyTaskPayload
|
||||
setRandomProjectColor(projectId: Int!): SetRandomProjectColorPayload
|
||||
updateTask(input: TaskInput!, taskId: Int!): UpdateTaskPayload
|
||||
}
|
||||
|
||||
|
@ -47,6 +48,15 @@ type Query {
|
|||
tasks(projectId: Int, status: TaskStatus!): [Task!]!
|
||||
}
|
||||
|
||||
"""
|
||||
Autogenerated return type of SetRandomProjectColor.
|
||||
"""
|
||||
type SetRandomProjectColorPayload {
|
||||
errors: [String!]!
|
||||
ok: Boolean!
|
||||
project: Project
|
||||
}
|
||||
|
||||
type Task {
|
||||
content: String!
|
||||
id: Int!
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { useSetRandomProjectColor } from "/hooks/mutations/useSetRandomProjectColor";
|
||||
import React, { useEffect } from "react";
|
||||
import { NavBar } from "/components/NavBar";
|
||||
import { useProjects } from "/hooks/queries/useProjects";
|
||||
|
@ -5,6 +6,7 @@ import { Project } from "/types/schema";
|
|||
|
||||
export function Projects() {
|
||||
const { data, loading } = useProjects();
|
||||
const setRandomProjectColor = useSetRandomProjectColor();
|
||||
const projects = data?.projects;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -29,8 +31,17 @@ export function Projects() {
|
|||
className="flex flex-row p-3 hover-bg-secondary w-full"
|
||||
key={i}
|
||||
>
|
||||
<div
|
||||
style={{ backgroundColor: project.color }}
|
||||
className="w-2/8 rounded w-12 h-12 mr-3 cursor-pointer"
|
||||
onClick={async () => {
|
||||
await setRandomProjectColor({
|
||||
variables: { projectId: project.id },
|
||||
});
|
||||
}}
|
||||
></div>
|
||||
<a
|
||||
className="no-underline text-accent block h-14"
|
||||
className="w-6/8 no-underline text-accent block h-14"
|
||||
href={`/tasks/#projectId=${project.id}`}
|
||||
>
|
||||
<span className="block w-full">{project.name}</span>
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import { ApolloCache, useMutation, gql } from "@apollo/client";
|
||||
import {
|
||||
SetRandomProjectColorPayload,
|
||||
MutationSetRandomProjectColorArgs,
|
||||
Project,
|
||||
} from "/types/schema";
|
||||
|
||||
const GQL = gql`
|
||||
mutation SetRandomProjectColor($projectId: Int!) {
|
||||
setRandomProjectColor(projectId: $projectId) {
|
||||
project {
|
||||
id
|
||||
color
|
||||
}
|
||||
errors
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type TArgs = {
|
||||
variables: { projectId: number };
|
||||
};
|
||||
|
||||
export function useSetRandomProjectColor() {
|
||||
const [setRandomProjectColor] = useMutation<
|
||||
SetRandomProjectColorPayload,
|
||||
MutationSetRandomProjectColorArgs
|
||||
>(GQL);
|
||||
|
||||
return ({ variables }: TArgs) => {
|
||||
return setRandomProjectColor({
|
||||
variables,
|
||||
update(cache, { data }) {
|
||||
const project: Project = data.project;
|
||||
modify(cache, project);
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const modify = (
|
||||
cache: ApolloCache<SetRandomProjectColorPayload>,
|
||||
project: Project,
|
||||
) => {
|
||||
cache.modify({
|
||||
id: cache.identify(project),
|
||||
fields: {
|
||||
projects(existingProjects = []) {
|
||||
cache.writeFragment({
|
||||
id: cache.identify(project),
|
||||
data: { project },
|
||||
fragment: gql`
|
||||
fragment P on Project {
|
||||
color
|
||||
}
|
||||
`,
|
||||
});
|
||||
return [...existingProjects, project];
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
|
@ -54,6 +54,7 @@ export type Mutation = {
|
|||
completeTask?: Maybe<CompleteTaskPayload>;
|
||||
createTask?: Maybe<CreateTaskPayload>;
|
||||
destroyTask?: Maybe<DestroyTaskPayload>;
|
||||
setRandomProjectColor?: Maybe<SetRandomProjectColorPayload>;
|
||||
updateTask?: Maybe<UpdateTaskPayload>;
|
||||
};
|
||||
|
||||
|
@ -69,6 +70,10 @@ export type MutationDestroyTaskArgs = {
|
|||
taskId: Scalars["Int"]["input"];
|
||||
};
|
||||
|
||||
export type MutationSetRandomProjectColorArgs = {
|
||||
projectId: Scalars["Int"]["input"];
|
||||
};
|
||||
|
||||
export type MutationUpdateTaskArgs = {
|
||||
input: TaskInput;
|
||||
taskId: Scalars["Int"]["input"];
|
||||
|
@ -99,6 +104,14 @@ export type QueryTasksArgs = {
|
|||
status: TaskStatus;
|
||||
};
|
||||
|
||||
/** Autogenerated return type of SetRandomProjectColor. */
|
||||
export type SetRandomProjectColorPayload = {
|
||||
__typename?: "SetRandomProjectColorPayload";
|
||||
errors: Array<Scalars["String"]["output"]>;
|
||||
ok: Scalars["Boolean"]["output"];
|
||||
project?: Maybe<Project>;
|
||||
};
|
||||
|
||||
export type Task = {
|
||||
__typename?: "Task";
|
||||
content: Scalars["String"]["output"];
|
||||
|
|
Loading…
Reference in a new issue