130 lines
3.3 KiB
TypeScript
130 lines
3.3 KiB
TypeScript
import { Instance, types } from 'mobx-state-tree';
|
|
import { RedmineTypes } from '../redmine-types';
|
|
import axios from 'axios';
|
|
|
|
export const IssueStore = types.frozen<RedmineTypes.ExtendedIssue>();
|
|
|
|
export type IIssueStore = Instance<typeof IssueStore>;
|
|
|
|
export const ColumnStore = types
|
|
.model({
|
|
status: '',
|
|
count: 0,
|
|
issues: types.array(IssueStore),
|
|
})
|
|
.views((self) => {
|
|
return {
|
|
get cards(): ICardStore[] {
|
|
return self.issues.map((issue) => {
|
|
return CardStore.create({
|
|
issue: issue,
|
|
});
|
|
});
|
|
},
|
|
};
|
|
});
|
|
|
|
export type IColumnStore = Instance<typeof ColumnStore>;
|
|
|
|
export const MetaInfoStore = types.model({
|
|
title: '',
|
|
url: types.maybe(types.string),
|
|
rootIssue: types.maybe(
|
|
types.model({
|
|
id: 0,
|
|
tracker: types.model({
|
|
id: 0,
|
|
name: '',
|
|
}),
|
|
subject: '',
|
|
}),
|
|
),
|
|
});
|
|
|
|
export type IMetaInfoStore = Instance<typeof MetaInfoStore>;
|
|
|
|
export const BoardStore = types.model({
|
|
data: types.array(ColumnStore),
|
|
metainfo: MetaInfoStore,
|
|
});
|
|
|
|
export type IBoardStore = Instance<typeof BoardStore>;
|
|
|
|
export const PageStore = types
|
|
.model({
|
|
loaded: false,
|
|
type: '',
|
|
name: '',
|
|
data: types.maybeNull(types.array(BoardStore)),
|
|
})
|
|
.actions((self) => {
|
|
return {
|
|
setData: (data: any) => {
|
|
console.debug('Kanban page store new data -', data); // DEBUG
|
|
self.data = data;
|
|
self.loaded = true;
|
|
},
|
|
};
|
|
})
|
|
.views((self) => {
|
|
return {
|
|
get issueIds(): number[] {
|
|
if (!self.data) return [];
|
|
const res = [] as number[];
|
|
for (let i = 0; i < self.data.length; i++) {
|
|
const iData = self.data[i];
|
|
for (let j = 0; j < iData.data.length; j++) {
|
|
const jData = iData.data[j];
|
|
for (let k = 0; k < jData.issues.length; k++) {
|
|
const issue = jData.issues[k];
|
|
if (res.indexOf(issue.id) < 0) {
|
|
res.push(issue.id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
},
|
|
get canTreeRefresh(): boolean {
|
|
return self.type === 'tree';
|
|
},
|
|
};
|
|
});
|
|
|
|
export async function PageStoreLoadData(store: IPageStore): Promise<void> {
|
|
const url = `${process.env.REACT_APP_BACKEND}simple-kanban-board/${store.type}/${store.name}/raw`;
|
|
const resp = await axios.get(url);
|
|
if (!resp?.data) return;
|
|
store.setData(resp.data);
|
|
}
|
|
|
|
export type IPageStore = Instance<typeof PageStore>;
|
|
|
|
export type CardField = {
|
|
component: string;
|
|
} & Record<string, any>;
|
|
|
|
export const CardParamsStore = types.optional(
|
|
types.model({
|
|
fields: types.array(types.frozen<CardField>()),
|
|
autoCollapse: types.boolean,
|
|
}),
|
|
{
|
|
fields: [
|
|
{ component: 'text', label: 'Исп.', path: 'current_user.name' },
|
|
{ component: 'text', label: 'Прио.', path: 'priority.name' },
|
|
{ component: 'text', label: 'Версия', path: 'fixed_version.name' },
|
|
{ component: 'text', label: 'Прогресс', path: 'done_ratio' },
|
|
{ component: 'labor_costs' },
|
|
{ component: 'tags', label: 'Tags', path: 'styledTags' },
|
|
],
|
|
autoCollapse: false,
|
|
},
|
|
);
|
|
|
|
export const CardStore = types.model({
|
|
issue: IssueStore,
|
|
params: CardParamsStore,
|
|
});
|
|
|
|
export type ICardStore = Instance<typeof CardStore>;
|