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/complete_task"
|
||||||
require_relative "../mutation/create_task"
|
require_relative "../mutation/create_task"
|
||||||
require_relative "../mutation/update_task"
|
require_relative "../mutation/update_task"
|
||||||
|
require_relative "../mutation/set_random_project_color"
|
||||||
field :destroy_task, mutation: Twenty::GraphQL::Mutation::DestroyTask
|
field :destroy_task, mutation: Twenty::GraphQL::Mutation::DestroyTask
|
||||||
field :complete_task, mutation: Twenty::GraphQL::Mutation::CompleteTask
|
field :complete_task, mutation: Twenty::GraphQL::Mutation::CompleteTask
|
||||||
field :create_task, mutation: Twenty::GraphQL::Mutation::CreateTask
|
field :create_task, mutation: Twenty::GraphQL::Mutation::CreateTask
|
||||||
field :update_task, mutation: Twenty::GraphQL::Mutation::UpdateTask
|
field :update_task, mutation: Twenty::GraphQL::Mutation::UpdateTask
|
||||||
|
field :set_random_project_color, mutation: Twenty::GraphQL::Mutation::SetRandomProjectColor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,6 +30,7 @@ type Mutation {
|
||||||
completeTask(taskId: Int!): CompleteTaskPayload
|
completeTask(taskId: Int!): CompleteTaskPayload
|
||||||
createTask(input: TaskInput!): CreateTaskPayload
|
createTask(input: TaskInput!): CreateTaskPayload
|
||||||
destroyTask(taskId: Int!): DestroyTaskPayload
|
destroyTask(taskId: Int!): DestroyTaskPayload
|
||||||
|
setRandomProjectColor(projectId: Int!): SetRandomProjectColorPayload
|
||||||
updateTask(input: TaskInput!, taskId: Int!): UpdateTaskPayload
|
updateTask(input: TaskInput!, taskId: Int!): UpdateTaskPayload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +48,15 @@ type Query {
|
||||||
tasks(projectId: Int, status: TaskStatus!): [Task!]!
|
tasks(projectId: Int, status: TaskStatus!): [Task!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
Autogenerated return type of SetRandomProjectColor.
|
||||||
|
"""
|
||||||
|
type SetRandomProjectColorPayload {
|
||||||
|
errors: [String!]!
|
||||||
|
ok: Boolean!
|
||||||
|
project: Project
|
||||||
|
}
|
||||||
|
|
||||||
type Task {
|
type Task {
|
||||||
content: String!
|
content: String!
|
||||||
id: Int!
|
id: Int!
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useSetRandomProjectColor } from "/hooks/mutations/useSetRandomProjectColor";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { NavBar } from "/components/NavBar";
|
import { NavBar } from "/components/NavBar";
|
||||||
import { useProjects } from "/hooks/queries/useProjects";
|
import { useProjects } from "/hooks/queries/useProjects";
|
||||||
|
@ -5,6 +6,7 @@ import { Project } from "/types/schema";
|
||||||
|
|
||||||
export function Projects() {
|
export function Projects() {
|
||||||
const { data, loading } = useProjects();
|
const { data, loading } = useProjects();
|
||||||
|
const setRandomProjectColor = useSetRandomProjectColor();
|
||||||
const projects = data?.projects;
|
const projects = data?.projects;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -29,8 +31,17 @@ export function Projects() {
|
||||||
className="flex flex-row p-3 hover-bg-secondary w-full"
|
className="flex flex-row p-3 hover-bg-secondary w-full"
|
||||||
key={i}
|
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
|
<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}`}
|
href={`/tasks/#projectId=${project.id}`}
|
||||||
>
|
>
|
||||||
<span className="block w-full">{project.name}</span>
|
<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>;
|
completeTask?: Maybe<CompleteTaskPayload>;
|
||||||
createTask?: Maybe<CreateTaskPayload>;
|
createTask?: Maybe<CreateTaskPayload>;
|
||||||
destroyTask?: Maybe<DestroyTaskPayload>;
|
destroyTask?: Maybe<DestroyTaskPayload>;
|
||||||
|
setRandomProjectColor?: Maybe<SetRandomProjectColorPayload>;
|
||||||
updateTask?: Maybe<UpdateTaskPayload>;
|
updateTask?: Maybe<UpdateTaskPayload>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,6 +70,10 @@ export type MutationDestroyTaskArgs = {
|
||||||
taskId: Scalars["Int"]["input"];
|
taskId: Scalars["Int"]["input"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MutationSetRandomProjectColorArgs = {
|
||||||
|
projectId: Scalars["Int"]["input"];
|
||||||
|
};
|
||||||
|
|
||||||
export type MutationUpdateTaskArgs = {
|
export type MutationUpdateTaskArgs = {
|
||||||
input: TaskInput;
|
input: TaskInput;
|
||||||
taskId: Scalars["Int"]["input"];
|
taskId: Scalars["Int"]["input"];
|
||||||
|
@ -99,6 +104,14 @@ export type QueryTasksArgs = {
|
||||||
status: TaskStatus;
|
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 = {
|
export type Task = {
|
||||||
__typename?: "Task";
|
__typename?: "Task";
|
||||||
content: Scalars["String"]["output"];
|
content: Scalars["String"]["output"];
|
||||||
|
|
Loading…
Reference in a new issue