509 lines
14 KiB
TypeScript
509 lines
14 KiB
TypeScript
'use client';
|
|
|
|
import { create } from 'zustand';
|
|
import dayjs from 'dayjs';
|
|
import { Integrations } from '@gitroom/frontend/components/launches/calendar.context';
|
|
import { createRef, RefObject } from 'react';
|
|
import { arrayMoveImmutable } from 'array-move';
|
|
import { PostComment } from '@gitroom/frontend/components/new-launch/providers/high.order.provider';
|
|
|
|
interface Values {
|
|
id: string;
|
|
content: string;
|
|
media: { id: string; path: string }[];
|
|
}
|
|
|
|
interface Internal {
|
|
integration: Integrations;
|
|
integrationValue: Values[];
|
|
}
|
|
|
|
interface SelectedIntegrations {
|
|
settings: any;
|
|
integration: Integrations;
|
|
ref?: RefObject<any>;
|
|
}
|
|
|
|
interface StoreState {
|
|
date: dayjs.Dayjs;
|
|
postComment: PostComment;
|
|
repeater?: number;
|
|
isCreateSet: boolean;
|
|
totalChars: number;
|
|
activateExitButton: boolean;
|
|
tags: { label: string; value: string }[];
|
|
tab: 0 | 1;
|
|
current: string;
|
|
locked: boolean;
|
|
hide: boolean;
|
|
setLocked: (locked: boolean) => void;
|
|
integrations: Integrations[];
|
|
selectedIntegrations: SelectedIntegrations[];
|
|
global: Values[];
|
|
internal: Internal[];
|
|
addGlobalValue: (index: number, value: Values[]) => void;
|
|
addInternalValue: (
|
|
index: number,
|
|
integrationId: string,
|
|
value: Values[]
|
|
) => void;
|
|
setGlobalValue: (value: Values[]) => void;
|
|
setInternalValue: (integrationId: string, value: Values[]) => void;
|
|
deleteGlobalValue: (index: number) => void;
|
|
deleteInternalValue: (integrationId: string, index: number) => void;
|
|
addRemoveInternal: (integrationId: string) => void;
|
|
changeOrderGlobal: (index: number, direction: 'up' | 'down') => void;
|
|
changeOrderInternal: (
|
|
integrationId: string,
|
|
index: number,
|
|
direction: 'up' | 'down'
|
|
) => void;
|
|
setGlobalValueText: (index: number, content: string) => void;
|
|
setGlobalValueMedia: (
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => void;
|
|
setInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => void;
|
|
addGlobalValueMedia: (
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => void;
|
|
removeGlobalValueMedia: (index: number, mediaIndex: number) => void;
|
|
setInternalValueText: (
|
|
integrationId: string,
|
|
index: number,
|
|
content: string
|
|
) => void;
|
|
addInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => void;
|
|
removeInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
mediaIndex: number
|
|
) => void;
|
|
setAllIntegrations: (integrations: Integrations[]) => void;
|
|
setCurrent: (current: string) => void;
|
|
addOrRemoveSelectedIntegration: (
|
|
integration: Integrations,
|
|
settings: any
|
|
) => void;
|
|
reset: () => void;
|
|
setSelectedIntegrations: (
|
|
params: { selectedIntegrations: Integrations; settings: any }[]
|
|
) => void;
|
|
setTab: (tab: 0 | 1) => void;
|
|
setHide: (hide: boolean) => void;
|
|
setDate: (date: dayjs.Dayjs) => void;
|
|
setRepeater: (repeater: number) => void;
|
|
setTags: (tags: { label: string; value: string }[]) => void;
|
|
setIsCreateSet: (isCreateSet: boolean) => void;
|
|
setTotalChars?: (totalChars: number) => void;
|
|
appendInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => void;
|
|
appendGlobalValueMedia: (
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => void;
|
|
setPostComment: (postComment: PostComment) => void;
|
|
setActivateExitButton?: (activateExitButton: boolean) => void;
|
|
}
|
|
|
|
const initialState = {
|
|
activateExitButton: true,
|
|
date: dayjs(),
|
|
postComment: PostComment.ALL,
|
|
tags: [] as { label: string; value: string }[],
|
|
totalChars: 0,
|
|
tab: 0 as 0,
|
|
isCreateSet: false,
|
|
current: 'global',
|
|
locked: false,
|
|
hide: false,
|
|
integrations: [] as Integrations[],
|
|
selectedIntegrations: [] as SelectedIntegrations[],
|
|
global: [] as Values[],
|
|
internal: [] as Internal[],
|
|
};
|
|
|
|
export const useLaunchStore = create<StoreState>()((set) => ({
|
|
...initialState,
|
|
setCurrent: (current: string) =>
|
|
set((state) => ({
|
|
current: current,
|
|
})),
|
|
addOrRemoveSelectedIntegration: (
|
|
integration: Integrations,
|
|
settings: any
|
|
) => {
|
|
set((state) => {
|
|
const existing = state.selectedIntegrations.find(
|
|
(i) => i.integration.id === integration.id
|
|
);
|
|
|
|
if (existing) {
|
|
return {
|
|
...(existing.integration.id === state.current
|
|
? { current: 'global' }
|
|
: {}),
|
|
selectedIntegrations: state.selectedIntegrations.filter(
|
|
(s, index) => s.integration.id !== existing.integration.id
|
|
),
|
|
};
|
|
}
|
|
|
|
return {
|
|
selectedIntegrations: [
|
|
...state.selectedIntegrations,
|
|
{ integration, settings, ref: createRef() },
|
|
],
|
|
};
|
|
});
|
|
},
|
|
addGlobalValue: (index: number, value: Values[]) =>
|
|
set((state) => {
|
|
if (!state.global.length) {
|
|
return { global: value };
|
|
}
|
|
|
|
return {
|
|
global: state.global.reduce((acc, item, i) => {
|
|
acc.push(item);
|
|
if (i === index) {
|
|
acc.push(...value);
|
|
}
|
|
return acc;
|
|
}, []),
|
|
};
|
|
}),
|
|
// Add value after index, similar to addGlobalValue, but for a speciic integration (index starts from 0)
|
|
addInternalValue: (index: number, integrationId: string, value: Values[]) =>
|
|
set((state) => {
|
|
const integrationIndex = state.internal.findIndex(
|
|
(i) => i.integration.id === integrationId
|
|
);
|
|
|
|
if (integrationIndex === -1) {
|
|
return {
|
|
internal: [
|
|
...state.internal,
|
|
{
|
|
integration: state.selectedIntegrations.find(
|
|
(i) => i.integration.id === integrationId
|
|
)!.integration,
|
|
integrationValue: value,
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
const updatedIntegration = state.internal[integrationIndex];
|
|
const newValues = updatedIntegration.integrationValue.reduce(
|
|
(acc, item, i) => {
|
|
acc.push(item);
|
|
if (i === index) {
|
|
acc.push(...value);
|
|
}
|
|
return acc;
|
|
},
|
|
[] as Values[]
|
|
);
|
|
|
|
return {
|
|
internal: state.internal.map((i, idx) =>
|
|
idx === integrationIndex ? { ...i, integrationValue: newValues } : i
|
|
),
|
|
};
|
|
}),
|
|
deleteGlobalValue: (index: number) =>
|
|
set((state) => ({
|
|
global: state.global.filter((_, i) => i !== index),
|
|
})),
|
|
deleteInternalValue: (integrationId: string, index: number) =>
|
|
set((state) => {
|
|
return {
|
|
internal: state.internal.map((i) => {
|
|
if (i.integration.id === integrationId) {
|
|
return {
|
|
...i,
|
|
integrationValue: i.integrationValue.filter(
|
|
(_, idx) => idx !== index
|
|
),
|
|
};
|
|
}
|
|
return i;
|
|
}),
|
|
};
|
|
}),
|
|
addRemoveInternal: (integrationId: string) =>
|
|
set((state) => {
|
|
const integration = state.selectedIntegrations.find(
|
|
(i) => i.integration.id === integrationId
|
|
);
|
|
const findIntegrationIndex = state.internal.findIndex(
|
|
(i) => i.integration.id === integrationId
|
|
);
|
|
|
|
if (findIntegrationIndex > -1) {
|
|
return {
|
|
internal: state.internal.filter(
|
|
(i) => i.integration.id !== integrationId
|
|
),
|
|
};
|
|
}
|
|
|
|
return {
|
|
internal: [
|
|
...state.internal,
|
|
{
|
|
integration: integration.integration,
|
|
integrationValue: state.global.slice(0).map((p) => p),
|
|
},
|
|
],
|
|
};
|
|
}),
|
|
changeOrderGlobal: (index: number, direction: 'up' | 'down') =>
|
|
set((state) => {
|
|
return {
|
|
global: arrayMoveImmutable(
|
|
state.global,
|
|
index,
|
|
direction === 'up' ? index - 1 : index + 1
|
|
),
|
|
};
|
|
}),
|
|
changeOrderInternal: (
|
|
integrationId: string,
|
|
index: number,
|
|
direction: 'up' | 'down'
|
|
) =>
|
|
set((state) => {
|
|
return {
|
|
internal: state.internal.map((item) => {
|
|
if (item.integration.id === integrationId) {
|
|
return {
|
|
...item,
|
|
integrationValue: arrayMoveImmutable(
|
|
item.integrationValue,
|
|
index,
|
|
direction === 'up' ? index - 1 : index + 1
|
|
),
|
|
};
|
|
}
|
|
|
|
return item;
|
|
}),
|
|
};
|
|
}),
|
|
setGlobalValueText: (index: number, content: string) =>
|
|
set((state) => ({
|
|
global: state.global.map((item, i) =>
|
|
i === index ? { ...item, content } : item
|
|
),
|
|
})),
|
|
setInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) => {
|
|
return set((state) => ({
|
|
internal: state.internal.map((item) =>
|
|
item.integration.id === integrationId
|
|
? {
|
|
...item,
|
|
integrationValue: item.integrationValue.map((v, i) =>
|
|
i === index ? { ...v, media } : v
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
}));
|
|
},
|
|
setGlobalValueMedia: (index: number, media: { id: string; path: string }[]) =>
|
|
set((state) => ({
|
|
global: state.global.map((item, i) =>
|
|
i === index ? { ...item, media } : item
|
|
),
|
|
})),
|
|
addGlobalValueMedia: (index: number, media: { id: string; path: string }[]) =>
|
|
set((state) => ({
|
|
global: state.global.map((item, i) =>
|
|
i === index ? { ...item, media: [...item.media, ...media] } : item
|
|
),
|
|
})),
|
|
removeGlobalValueMedia: (index: number, mediaIndex: number) =>
|
|
set((state) => ({
|
|
global: state.global.map((item, i) =>
|
|
i === index
|
|
? {
|
|
...item,
|
|
media: item.media.filter((_, idx) => idx !== mediaIndex),
|
|
}
|
|
: item
|
|
),
|
|
})),
|
|
setInternalValueText: (
|
|
integrationId: string,
|
|
index: number,
|
|
content: string
|
|
) => {
|
|
set((state) => ({
|
|
internal: state.internal.map((item) =>
|
|
item.integration.id === integrationId
|
|
? {
|
|
...item,
|
|
integrationValue: item.integrationValue.map((v, i) =>
|
|
i === index ? { ...v, content } : v
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
}));
|
|
},
|
|
addInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) =>
|
|
set((state) => ({
|
|
internal: state.internal.map((item) =>
|
|
item.integration.id === integrationId
|
|
? {
|
|
...item,
|
|
integrationValue: item.integrationValue.map((v, i) =>
|
|
i === index ? { ...v, media: [...v.media, ...media] } : v
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
})),
|
|
removeInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
mediaIndex: number
|
|
) =>
|
|
set((state) => ({
|
|
internal: state.internal.map((item) =>
|
|
item.integration.id === integrationId
|
|
? {
|
|
...item,
|
|
integrationValue: item.integrationValue.map((v, i) =>
|
|
i === index
|
|
? {
|
|
...v,
|
|
media: v.media.filter((_, idx) => idx !== mediaIndex),
|
|
}
|
|
: v
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
})),
|
|
reset: () =>
|
|
set((state) => ({
|
|
...state,
|
|
...initialState,
|
|
})),
|
|
setAllIntegrations: (integrations: Integrations[]) =>
|
|
set((state) => ({
|
|
integrations: integrations,
|
|
})),
|
|
setTab: (tab: 0 | 1) =>
|
|
set((state) => ({
|
|
tab: tab,
|
|
})),
|
|
setLocked: (locked: boolean) =>
|
|
set((state) => ({
|
|
locked: locked,
|
|
})),
|
|
setHide: (hide: boolean) =>
|
|
set((state) => ({
|
|
hide: hide,
|
|
})),
|
|
setDate: (date: dayjs.Dayjs) =>
|
|
set((state) => ({
|
|
date,
|
|
})),
|
|
setRepeater: (repeater: number) =>
|
|
set((state) => ({
|
|
repeater,
|
|
})),
|
|
setTags: (tags: { label: string; value: string }[]) =>
|
|
set((state) => ({
|
|
tags,
|
|
})),
|
|
setIsCreateSet: (isCreateSet: boolean) =>
|
|
set((state) => ({
|
|
isCreateSet,
|
|
})),
|
|
setSelectedIntegrations: (
|
|
params: { selectedIntegrations: Integrations; settings: any }[]
|
|
) =>
|
|
set((state) => ({
|
|
selectedIntegrations: params.map((p) => ({
|
|
integration: p.selectedIntegrations,
|
|
settings: p.settings,
|
|
ref: createRef(),
|
|
})),
|
|
})),
|
|
setGlobalValue: (value: Values[]) =>
|
|
set((state) => ({
|
|
global: value,
|
|
})),
|
|
setInternalValue: (integrationId: string, value: Values[]) =>
|
|
set((state) => ({
|
|
internal: state.internal.map((item) =>
|
|
item.integration.id === integrationId
|
|
? { ...item, integrationValue: value }
|
|
: item
|
|
),
|
|
})),
|
|
setTotalChars: (totalChars: number) =>
|
|
set((state) => ({
|
|
totalChars,
|
|
})),
|
|
appendInternalValueMedia: (
|
|
integrationId: string,
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) =>
|
|
set((state) => ({
|
|
internal: state.internal.map((item) =>
|
|
item.integration.id === integrationId
|
|
? {
|
|
...item,
|
|
integrationValue: item.integrationValue.map((v, i) =>
|
|
i === index ? { ...v, media: [...v.media, ...media] } : v
|
|
),
|
|
}
|
|
: item
|
|
),
|
|
})),
|
|
appendGlobalValueMedia: (
|
|
index: number,
|
|
media: { id: string; path: string }[]
|
|
) =>
|
|
set((state) => ({
|
|
global: state.global.map((item, i) =>
|
|
i === index ? { ...item, media: [...item.media, ...media] } : item
|
|
),
|
|
})),
|
|
setPostComment: (postComment: PostComment) =>
|
|
set((state) => ({
|
|
postComment,
|
|
})),
|
|
setActivateExitButton: (activateExitButton: boolean) =>
|
|
set((state) => ({
|
|
activateExitButton,
|
|
})),
|
|
}));
|