repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
Projectflow
stars
latest
clone command
git clone gitlawb://did:key:z6Mkfh4Y...QBEi/projectflowgit clone gitlawb://did:key:z6Mkfh4Y.../projectflowb3cded1async from playground1d ago| #1 | import { StateCreator } from "zustand"; |
| #2 | import type { Issue } from "../../../domain/entities"; |
| #3 | import { issues as mockIssues } from "../../../infrastructure/mock-data/issues"; |
| #4 | import { generateId } from "../../../infrastructure/helpers"; |
| #5 | import type { StoreState } from "../store.types"; |
| #6 | |
| #7 | export interface IssueSlice { |
| #8 | issues: Issue[]; |
| #9 | currentIssue: Issue | null; |
| #10 | setCurrentIssue: (issue: Issue | null) => void; |
| #11 | createIssue: ( |
| #12 | issue: Omit<Issue, "id" | "createdAt" | "updatedAt"> |
| #13 | ) => Issue; |
| #14 | updateIssue: (id: string, updates: Partial<Issue>) => void; |
| #15 | deleteIssue: (id: string) => void; |
| #16 | moveIssue: (id: string, status: Issue["status"]) => void; |
| #17 | } |
| #18 | |
| #19 | export const createIssueSlice: StateCreator< |
| #20 | StoreState, |
| #21 | [], |
| #22 | [], |
| #23 | IssueSlice |
| #24 | > = (set, get) => ({ |
| #25 | issues: mockIssues, |
| #26 | currentIssue: null, |
| #27 | setCurrentIssue: (issue) => set({ currentIssue: issue }), |
| #28 | createIssue: (issueData) => { |
| #29 | const project = get().projects.find( |
| #30 | (p) => p.id === issueData.projectId |
| #31 | ); |
| #32 | const projectIssues = get().issues.filter( |
| #33 | (i) => i.projectId === issueData.projectId |
| #34 | ); |
| #35 | const prefix = project |
| #36 | ? project.name |
| #37 | .split(" ") |
| #38 | .map((w) => w[0]) |
| #39 | .join("") |
| #40 | .toUpperCase() |
| #41 | .slice(0, 3) |
| #42 | : "ISS"; |
| #43 | const newIssue: Issue = { |
| #44 | ...issueData, |
| #45 | id: generateId(), |
| #46 | identifier: `${prefix}-${projectIssues.length + 1}`, |
| #47 | createdAt: new Date().toISOString(), |
| #48 | updatedAt: new Date().toISOString(), |
| #49 | }; |
| #50 | set((s) => ({ issues: [...s.issues, newIssue] })); |
| #51 | get().addActivity({ |
| #52 | issueId: newIssue.id, |
| #53 | userId: get().currentUser?.id || "u1", |
| #54 | type: "created", |
| #55 | }); |
| #56 | return newIssue; |
| #57 | }, |
| #58 | updateIssue: (id, updates) => { |
| #59 | const oldIssue = get().issues.find((i) => i.id === id); |
| #60 | set((s) => ({ |
| #61 | issues: s.issues.map((i) => |
| #62 | i.id === id |
| #63 | ? { ...i, ...updates, updatedAt: new Date().toISOString() } |
| #64 | : i |
| #65 | ), |
| #66 | currentIssue: |
| #67 | s.currentIssue?.id === id |
| #68 | ? { |
| #69 | ...s.currentIssue, |
| #70 | ...updates, |
| #71 | updatedAt: new Date().toISOString(), |
| #72 | } |
| #73 | : s.currentIssue, |
| #74 | })); |
| #75 | if (oldIssue && updates.status && updates.status !== oldIssue.status) { |
| #76 | get().addActivity({ |
| #77 | issueId: id, |
| #78 | userId: get().currentUser?.id || "u1", |
| #79 | type: "status_change", |
| #80 | oldValue: oldIssue.status, |
| #81 | newValue: updates.status, |
| #82 | }); |
| #83 | } |
| #84 | if ( |
| #85 | oldIssue && |
| #86 | updates.assigneeId !== undefined && |
| #87 | updates.assigneeId !== oldIssue.assigneeId |
| #88 | ) { |
| #89 | get().addActivity({ |
| #90 | issueId: id, |
| #91 | userId: get().currentUser?.id || "u1", |
| #92 | type: "assignment", |
| #93 | newValue: updates.assigneeId || undefined, |
| #94 | }); |
| #95 | } |
| #96 | }, |
| #97 | deleteIssue: (id) => { |
| #98 | set((s) => ({ |
| #99 | issues: s.issues.filter((i) => i.id !== id), |
| #100 | currentIssue: s.currentIssue?.id === id ? null : s.currentIssue, |
| #101 | comments: s.comments.filter((c) => c.issueId !== id), |
| #102 | activities: s.activities.filter((a) => a.issueId !== id), |
| #103 | })); |
| #104 | }, |
| #105 | moveIssue: (id, status) => { |
| #106 | get().updateIssue(id, { status }); |
| #107 | }, |
| #108 | }); |
| #109 |