lodash#min TypeScript Examples
The following examples show how to use
lodash#min.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
/**
* Creates Analysis result legend based on data returned from API.
*
* The equal interval method takes the maximum values minus the minimum
* and divides the result by the number of classes, which is the length
* of colors array.
*
* Finally the function calculates the upper end of each class interval
* and assigns a color.
*
* @return LegendDefinition
*/
export function createLegendFromFeatureArray(
features: Feature[],
statistic: AggregationOperations,
): LegendDefinition {
// Extract values based on aggregation operation.
const stats: number[] = features.map(f =>
f.properties && f.properties[statistic] ? f.properties[statistic] : 0,
);
const maxNum = Math.max(...stats);
const minNum = Math.min(...stats);
const colors = ['#fee5d9', '#fcae91', '#fb6a4a', '#de2d26', '#a50f15'];
const delta = (maxNum - minNum) / colors.length;
const legend: LegendDefinition = colors.map((color, index) => {
const breakpoint = Math.ceil(minNum + (index + 1) * delta);
// Make sure you don't have a value greater than maxNum.
const value = Math.min(breakpoint, maxNum);
return { value, color };
});
return legend;
}
Example #2
Source File: analysis-utils.ts From prism-frontend with MIT License | 7 votes |
operations = {
min: (data: number[]) => min(data),
max: (data: number[]) => max(data),
sum, // sum method directly from lodash
mean, // mean method directly from lodash
median: (data: number[]) => {
// eslint-disable-next-line fp/no-mutating-methods
const sortedValues = [...data].sort();
// Odd cases we use the middle value
if (sortedValues.length % 2 !== 0) {
return sortedValues[Math.floor(sortedValues.length / 2)];
}
// Even cases we average the two middles
const floor = sortedValues.length / 2 - 1;
const ceil = sortedValues.length / 2;
return (sortedValues[floor] + sortedValues[ceil]) / 2;
},
}
Example #3
Source File: utils.ts From gant-design with MIT License | 7 votes |
export function getAllChildrenNode(
targetKeys: any[],
api: GridApi,
deleteChildren = false,
): RowNode[] {
const targetNodes: RowNode[] = [];
targetKeys.map(key => {
const itemNode = api.getRowNode(key);
itemNode && targetNodes.push(itemNode);
});
if (deleteChildren) return targetNodes;
const allNodes: RowNode[] = [];
const groupNodes = groupBy(targetNodes, 'level');
let level = min(Object.keys(groupNodes).map(level => level));
while (!isEmpty(groupNodes[level])) {
const list = groupNodes[level];
let nextLevel: any = parseInt(level) + 1;
nextLevel = nextLevel.toString();
groupNodes[nextLevel] = groupNodes[nextLevel] ? groupNodes[nextLevel] : [];
list.map(itemNode => {
const { childrenAfterGroup = [] } = itemNode as RowNode;
groupNodes[nextLevel].push(...childrenAfterGroup);
return itemNode.data;
});
groupNodes[nextLevel] = uniqBy(groupNodes[nextLevel], 'id');
allNodes.push(...list);
level = nextLevel;
}
return allNodes;
}
Example #4
Source File: base-data-set.ts From S2 with MIT License | 6 votes |
public getValueRangeByField(field: string): ValueRange {
const cacheRange = getValueRangeState(this.spreadsheet, field);
if (cacheRange) {
return cacheRange;
}
const fieldValues = compact(
map(this.originData, (item) => {
const value = item[field] as string;
return isNil(value) ? null : Number.parseFloat(value);
}),
);
const range = {
maxValue: max(fieldValues),
minValue: min(fieldValues),
};
setValueRangeState(this.spreadsheet, {
[field]: range,
});
return range;
}
Example #5
Source File: github_analyzer.ts From CIAnalyzer with MIT License | 5 votes |
createWorkflowReport(workflowName: string, workflow: WorkflowRunsItem, jobs: JobsItem, tagMap: RepositoryTagMap): WorkflowReport {
const { workflowId, buildNumber, workflowRunId }
= this.createWorkflowParams(workflowName, workflow)
const jobReports: JobReport[] = jobs.map((job) => {
const stepReports: StepReport[] = job.steps!.map((step) => {
const startedAt = new Date(step.started_at!)
const completedAt = new Date(step.completed_at!)
// step
return {
name: step.name,
status: this.normalizeStatus(step.conclusion),
number: step.number,
startedAt,
completedAt,
stepDurationSec: diffSec(startedAt, completedAt)
}
})
const startedAt = new Date(job.started_at)
const completedAt = new Date(job.completed_at!)
// job
return {
workflowRunId: workflowRunId,
buildNumber: buildNumber, // Github Actions job does not have buildNumber
jobId: String(job.id),
jobName: job.name,
status: this.normalizeStatus(job.conclusion),
startedAt,
completedAt,
jobDurationSec: diffSec(startedAt, completedAt),
sumStepsDurationSec: sumBy(stepReports, 'stepDurationSec'),
steps: stepReports,
url: job.html_url ?? '',
executorClass: '',
executorType: '',
executorName: job.runner_name ?? '',
}
})
const createdAt = new Date(workflow.created_at)
const startedAt = min(jobReports.map((job) => job.startedAt )) || createdAt
const completedAt = max(jobReports.map((job) => job.completedAt )) || createdAt
const status = this.normalizeStatus(workflow.conclusion as unknown as string)
// workflow
return {
service: 'github',
workflowId,
buildNumber,
workflowRunId,
workflowName,
createdAt,
trigger: workflow.event,
status,
repository: workflow.repository.full_name,
headSha: workflow.head_sha,
branch: workflow.head_branch ?? '',
tag: tagMap.get(workflow.head_sha) ?? '',
jobs: jobReports,
startedAt,
completedAt,
workflowDurationSec: diffSec(startedAt, completedAt),
sumJobsDurationSec: sumBy(jobReports, 'sumStepsDurationSec'),
successCount: (status === 'SUCCESS') ? 1 : 0,
parameters: [],
queuedDurationSec: diffSec(createdAt, startedAt),
commitMessage: workflow.head_commit?.message ?? '',
actor: workflow.head_commit?.author?.name ?? '',
url: workflow.html_url,
}
}
Example #6
Source File: date-helper.ts From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
ganttDateRange = (tasks: Task[], viewMode: ViewMode) => {
let newStartDate: Date = tasks[0].start || 0;
let newEndDate: Date = tasks[0].start || 0;
const timeArr = compact(flatten(tasks.map((item) => [item.start, item.end])));
const minTime = min(timeArr);
const maxTime = max(timeArr);
newStartDate = minTime && new Date(minTime);
newEndDate = maxTime && new Date(maxTime);
if (!newStartDate) {
newStartDate = new Date(moment().subtract(15, 'days'));
}
if (!newEndDate || newEndDate.getTime() === newStartDate.getTime()) {
newEndDate = new Date(moment(newStartDate).subtract(-30, 'days'));
}
// start time is bigger then end time
if (newStartDate.getTime() > newEndDate.getTime()) {
[newStartDate, newEndDate] = [newEndDate, newStartDate];
}
switch (viewMode) {
case ViewMode.Month:
newStartDate = addToDate(newStartDate, -1, 'month');
newStartDate = startOfDate(newStartDate, 'month');
newEndDate = addToDate(newEndDate, 1, 'year');
newEndDate = startOfDate(newEndDate, 'year');
break;
case ViewMode.Week:
newStartDate = startOfDate(newStartDate, 'day');
newEndDate = startOfDate(newEndDate, 'day');
newStartDate = addToDate(getMonday(newStartDate), -7, 'day');
newEndDate = addToDate(newEndDate, 1.5, 'month');
break;
case ViewMode.Day:
newStartDate = startOfDate(newStartDate, 'day');
newEndDate = startOfDate(newEndDate, 'day');
newStartDate = addToDate(newStartDate, -1, 'day');
newEndDate = addToDate(newEndDate, 19, 'day');
break;
case ViewMode.QuarterDay:
newStartDate = startOfDate(newStartDate, 'day');
newEndDate = startOfDate(newEndDate, 'day');
newStartDate = addToDate(newStartDate, -1, 'day');
newEndDate = addToDate(newEndDate, 66, 'hour'); // 24(1 day)*3 - 6
break;
case ViewMode.HalfDay:
newStartDate = startOfDate(newStartDate, 'day');
newEndDate = startOfDate(newEndDate, 'day');
newStartDate = addToDate(newStartDate, -1, 'day');
newEndDate = addToDate(newEndDate, 108, 'hour'); // 24(1 day)*5 - 12
break;
default:
break;
}
return [newStartDate, newEndDate];
}
Example #7
Source File: circleci_analyzer.ts From CIAnalyzer with MIT License | 4 votes |
createWorkflowReport( workflowRun: WorkflowRun, jobs: SingleBuildResponse[], tagMap: RepositoryTagMap): WorkflowReport {
const sortedJobs = sortBy(jobs, 'build_num')
const firstJob = first(sortedJobs)!
const lastJob = last(sortedJobs)!
const repository = `${firstJob.username}/${firstJob.reponame}`
const { workflowName, workflowId, buildNumber, workflowRunId }
= this.createWorkflowParams(workflowRun.workflow_name, repository, lastJob.build_num)
const jobReports: JobReport[] = sortedJobs.map((job) => {
const stepReports: StepReport[] = job.steps
.filter((step) => {
const action = first(step.actions)!
// NOTE: Ignore background step (ex. Setup service container image step)
return action.background === false
})
.map((step) => {
const action = first(step.actions)!
const startedAt = new Date(action.start_time)
// NOTE: Sometimes action.end_time will be broken, so it should be replaced when it's value is invalid.
const validatedEndTime = action.end_time ?? action.start_time
const completedAt = new Date(validatedEndTime)
// step
return {
name: action.name,
status: this.normalizeStatus(action.status),
number: action.step,
startedAt,
completedAt,
stepDurationSec: diffSec(startedAt, completedAt)
}
})
const startedAt = new Date(job.start_time)
const completedAt = new Date(job.stop_time)
// job
return {
workflowRunId,
buildNumber: job.build_num,
jobId: job.workflows.job_id,
jobName: job.workflows.job_name,
status: this.normalizeStatus(job.status),
startedAt,
completedAt,
jobDurationSec: diffSec(startedAt, completedAt),
sumStepsDurationSec: secRound(sumBy(stepReports, 'stepDurationSec')),
steps: stepReports,
url: '',
executorClass: '',
executorType: '',
executorName: '',
}
})
const startedAt = min(jobReports.map((job) => job.startedAt ))!
const completedAt = max(jobReports.map((job) => job.completedAt ))!
const status = this.estimateWorkflowStatus(jobReports)
const createdAt = min(jobs.map((job) => new Date(job.queued_at)))!
// workflow
return {
service: 'circleci',
workflowId,
buildNumber,
workflowRunId,
workflowName,
createdAt,
trigger: firstJob.why,
status,
repository,
headSha: firstJob.vcs_revision,
branch: firstJob.branch,
tag: tagMap.get(firstJob.vcs_revision) ?? '',
jobs: jobReports,
startedAt,
completedAt,
workflowDurationSec: diffSec(startedAt, completedAt),
sumJobsDurationSec: secRound(sumBy(jobReports, 'sumStepsDurationSec')),
successCount: (status === 'SUCCESS') ? 1 : 0,
parameters: [],
queuedDurationSec: diffSec(createdAt, min(jobs.map((job) => new Date(job.start_time)))!),
commitMessage: '',
actor: '',
url: '',
}
}
Example #8
Source File: philosophers.tsx From S2 with MIT License | 4 votes |
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/24cac0f7-70f0-4131-be61-df11da3ca921.json',
)
.then((res) => res.json())
.then((data) => {
const weights = data.map((item) => item.weight);
const maxWeight = max(weights);
const minWeight = min(weights);
const weightSpan = maxWeight - minWeight;
const PaletteLegend = () => (
<div className="legend">
<div className="legend-limit">{minWeight.toFixed(2)}</div>
{PALETTE_COLORS.map((color, index) => (
<span
key={index}
className="legend-color"
style={{ background: color }}
/>
))}
<div className="legend-limit">{maxWeight.toFixed(2)}</div>
</div>
);
const getFormatter = (val) => {
if (val < 0) {
return `公元前${replace(val, '-', '')}年`;
} else {
return `${val}年`;
}
};
const s2DataConfig = {
fields: {
rows: ['country', 'name', 'start', 'end', 'points', 'word'],
columns: [],
values: ['weight'],
},
meta: [
{
field: 'word',
name: '关键词',
},
{
field: 'points',
name: '观点',
},
{
field: 'name',
name: '姓名',
},
{
field: 'country',
name: '国家',
},
{
field: 'start',
name: '出生',
formatter: getFormatter,
},
{
field: 'end',
name: '逝世',
formatter: getFormatter,
},
{
field: 'weight',
name: '权重',
formatter: (val) => val.toFixed(2),
},
],
data,
};
const TooltipContent = (props) => {
const { rowQuery, fieldValue } = props;
const { name, country, start, end, points } = rowQuery;
const ponitsLines = points.split('&');
return (
<div className="antv-s2-tooltip-container">
<div className="antv-s2-tooltip-head-info-list">
<div>姓名:{name}</div>
<div>国家:{country}</div>
<div>出生:{getFormatter(start)}</div>
<div>逝世:{getFormatter(end)}</div>
{ponitsLines.length > 1 ? (
<div>
观点:
{ponitsLines.map((point, index) => (
<div>
{index + 1}: {point}
</div>
))}
</div>
) : (
<div>观点: {ponitsLines[0]}</div>
)}
</div>
<div className="antv-s2-tooltip-divider"></div>
<div className="antv-s2-tooltip-detail-list">
<div className="antv-s2-tooltip-detail-item">
<span className="antv-s2-tooltip-detail-item-key">权重</span>
<span className="antv-s2-tooltip-detail-item-val">
{fieldValue}
</span>
</div>
</div>
</div>
);
};
const s2Options = {
width: '',
height: 400,
conditions: {
text: [
{
field: 'weight',
mapping(value) {
if (value >= 20) {
return {
fill: '#fff',
};
}
},
},
],
background: [
{
field: 'weight',
mapping(value) {
let backgroundColor;
const colorIndex =
Math.floor(
(((value - minWeight) / weightSpan) * 100) /
PALETTE_COLORS.length,
) - 1;
if (colorIndex <= 0) {
backgroundColor = PALETTE_COLORS[0];
} else if (colorIndex >= PALETTE_COLORS.length) {
backgroundColor = PALETTE_COLORS[PALETTE_COLORS.length - 1];
} else {
backgroundColor = PALETTE_COLORS[colorIndex];
}
return {
fill: backgroundColor,
};
},
},
],
},
interaction: {
selectedCellsSpotlight: false,
hoverHighlight: false,
},
};
const onDataCellMouseUp = (value) => {
const viewMeta = value?.viewMeta;
if (!viewMeta) {
return;
}
const position = {
x: value.event.clientX,
y: value.event.clientY,
};
viewMeta.spreadsheet.tooltip.show({
position,
content: TooltipContent(viewMeta),
});
};
ReactDOM.render(
<SheetComponent
dataCfg={s2DataConfig}
options={s2Options}
adaptive={true}
header={{
title: '哲学家的观点',
extra: [<PaletteLegend />],
}}
onDataCellMouseUp={onDataCellMouseUp}
/>,
document.getElementById('container'),
);
});
Example #9
Source File: time-series.spec.ts From aqualink-app with MIT License | 4 votes |
timeSeriesTests = () => {
const testService = TestService.getInstance();
let app: INestApplication;
let surveyPointDataRange: StringDateRange = [
new Date(0).toISOString(),
new Date().toISOString(),
];
let siteDataRange: StringDateRange = [
new Date(0).toISOString(),
new Date().toISOString(),
];
beforeAll(async () => {
app = await testService.getApp();
});
it('GET /sites/:siteId/site-survey-points/:surveyPointId/range fetch range of poi data', async () => {
const rsp = await request(app.getHttpServer()).get(
`/time-series/sites/${athensSite.id}/site-survey-points/${athensSurveyPointPiraeus.id}/range`,
);
expect(rsp.status).toBe(200);
const metrics = union(hoboMetrics, NOAAMetrics);
metrics.forEach((metric) => {
expect(rsp.body).toHaveProperty(metric);
});
hoboMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.HOBO);
expect(rsp.body[metric][SourceType.HOBO].data.length).toBe(1);
const { minDate, maxDate } = rsp.body[metric][SourceType.HOBO].data[0];
const [startDate, endDate] = surveyPointDataRange;
surveyPointDataRange = [
min([minDate, startDate]),
max([maxDate, endDate]),
];
});
NOAAMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.NOAA);
expect(rsp.body[metric][SourceType.NOAA].data.length).toBe(1);
const { minDate, maxDate } = rsp.body[metric][SourceType.NOAA].data[0];
const [startDate, endDate] = surveyPointDataRange;
surveyPointDataRange = [
min([minDate, startDate]),
max([maxDate, endDate]),
];
});
});
it('GET /sites/:id/range fetch range of site data', async () => {
const rsp = await request(app.getHttpServer()).get(
`/time-series/sites/${californiaSite.id}/range`,
);
expect(rsp.status).toBe(200);
const metrics = union(NOAAMetrics, spotterMetrics);
metrics.forEach((metric) => {
expect(rsp.body).toHaveProperty(metric);
});
NOAAMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.NOAA);
expect(rsp.body[metric][SourceType.NOAA].data.length).toBe(1);
const { minDate, maxDate } = rsp.body[metric][SourceType.NOAA].data[0];
const [startDate, endDate] = siteDataRange;
siteDataRange = [min([minDate, startDate]), max([maxDate, endDate])];
});
spotterMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.SPOTTER);
expect(rsp.body[metric][SourceType.SPOTTER].data.length).toBe(1);
const { minDate, maxDate } = rsp.body[metric][SourceType.SPOTTER].data[0];
const [startDate, endDate] = siteDataRange;
siteDataRange = [min([minDate, startDate]), max([maxDate, endDate])];
});
});
it('GET /sites/:siteId/site-survey-points/:surveyPointId fetch poi data', async () => {
const [startDate, endDate] = surveyPointDataRange;
const rsp = await request(app.getHttpServer())
.get(
`/time-series/sites/${athensSite.id}/site-survey-points/${athensSurveyPointPiraeus.id}`,
)
.query({
// Increase the search window to combat precision issues with the dates
start: moment(startDate).subtract(1, 'minute').toISOString(),
end: moment(endDate).add(1, 'day').toISOString(),
metrics: hoboMetrics.concat(NOAAMetrics),
hourly: false,
});
expect(rsp.status).toBe(200);
const metrics = union(hoboMetrics, NOAAMetrics);
metrics.forEach((metric) => {
expect(rsp.body).toHaveProperty(metric);
});
hoboMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.HOBO);
expect(rsp.body[metric][SourceType.HOBO].data.length).toBe(10);
});
NOAAMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.NOAA);
expect(rsp.body[metric][SourceType.NOAA].data.length).toBe(10);
});
});
it('GET /sites/:siteId fetch site data', async () => {
const [startDate, endDate] = siteDataRange;
const rsp = await request(app.getHttpServer())
.get(`/time-series/sites/${californiaSite.id}`)
.query({
// Increase the search window to combat precision issues with the dates
start: moment(startDate).subtract(1, 'minute').toISOString(),
end: moment(endDate).add(1, 'day').toISOString(),
metrics: spotterMetrics.concat(NOAAMetrics),
hourly: false,
});
expect(rsp.status).toBe(200);
const metrics = union(NOAAMetrics, spotterMetrics);
metrics.forEach((metric) => {
expect(rsp.body).toHaveProperty(metric);
});
NOAAMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.NOAA);
expect(rsp.body[metric][SourceType.NOAA].data.length).toBe(10);
});
spotterMetrics.forEach((metric) => {
expect(rsp.body[metric]).toHaveProperty(SourceType.SPOTTER);
expect(rsp.body[metric][SourceType.SPOTTER].data.length).toBe(10);
});
});
}
Example #10
Source File: TaskCalendar.tsx From next-basics with GNU General Public License v3.0 | 4 votes |
export function TaskCalendar(props: TaskCalendarProps): React.ReactElement {
const {
briefList,
taskList,
importantList,
importanceSettings,
taskSettings,
onDateSelect,
onPickerPanelChange,
value,
defaultSelectedDate,
footerStyle,
dateCellHeight,
showLunarInfo,
mode,
} = props;
const [selectedData, setSelectedData] = useState<{
date: Moment;
data: DateDetail["data"];
}>({} as any);
const briefDataMap = useMemo(() => {
return briefList?.reduce((pre, cur) => {
const curMoment = moment(cur.date).format("YYYY-MM-DD");
pre[curMoment] = cur.text;
return pre;
}, {} as Record<BriefData["date"], BriefData["text"]>);
}, [briefList]);
const taskDataMap = useMemo(() => {
return taskList?.reduce((pre, cur) => {
const curMoment = moment(cur.date).format("YYYY-MM-DD");
pre[curMoment] = cur.task;
return pre;
}, {} as Record<TaskData["date"], TaskData["task"]>);
}, [taskList]);
const importantDataMap = useMemo(() => {
return importantList?.reduce((pre, cur) => {
const curMoment = moment(cur.date).format("YYYY-MM-DD");
pre[curMoment] = cur.issues;
return pre;
}, {} as Record<ImportantData["date"], ImportantData["issues"]>);
}, [importantList]);
const pickerValue = useMemo(() => {
return moment(value);
}, [value]);
useEffect(() => {
const now = moment(defaultSelectedDate || value);
const formatDate = now.format("YYYY-MM-DD");
const curBriefData = briefDataMap?.[formatDate];
const curTaskData = taskDataMap?.[formatDate];
const curImportantData = importantDataMap?.[formatDate];
const curData = {
brief: curBriefData,
task: curTaskData,
importance: curImportantData,
};
setSelectedData({ date: now, data: curData });
}, [briefDataMap, defaultSelectedDate, importantDataMap, taskDataMap, value]);
const dateRender = useCallback(
(date: Moment) => {
let solar2lunarData;
if (showLunarInfo) {
solar2lunarData = solarLunar.solar2lunar(
date.year(),
date.month() + 1,
date.date()
);
}
const formatDate = date.format("YYYY-MM-DD");
const curBriefData = briefDataMap?.[formatDate];
const curTaskData = taskDataMap?.[formatDate];
const curImportantData = importantDataMap?.[formatDate];
const taskColor =
taskSettings?.colorMap?.[
min(
curTaskData?.map((task) =>
get(task, taskSettings?.fields?.priority)
)
)
];
const importanceColor =
importanceSettings?.colorMap?.[
importanceSettings?.priority?.find((type) =>
curImportantData?.includes(type)
)
];
return (
<div
className={classNames(styles.dateContainer, {
[styles.importantDay]: !!importanceColor,
[styles.today]: date.isSame(pickerValue, "date"),
})}
style={{
borderColor: date.isSame(selectedData.date, "date")
? "var(--color-auxiliary-text)"
: importanceColor,
backgroundColor: importanceColor,
height: dateCellHeight,
}}
>
{curBriefData && (
<div className={styles.briefText}>{curBriefData}</div>
)}
{!isNil(taskColor) && (
<div
className={styles.taskPoint}
style={{
backgroundColor: taskColor,
}}
></div>
)}
<div className={styles.dateMain}>
<div className={styles.dateNumber}>{date.date()}</div>
{showLunarInfo && (
<div className={styles.dateText}>{solar2lunarData.dayCn}</div>
)}
</div>
</div>
);
},
[
briefDataMap,
taskDataMap,
importantDataMap,
taskSettings,
importanceSettings,
selectedData,
pickerValue,
dateCellHeight,
showLunarInfo,
]
);
const extraFooterNode = useMemo(() => {
if (isEmpty(selectedData)) return;
const {
date,
data: { importance, task },
} = selectedData;
return (
<div className={styles.calendarFooter} style={footerStyle}>
<div className={styles.dateInfo}>
<div className={styles.dateText}>{date.format("LL")}</div>
{importance?.length > 0 && !isEmpty(importanceSettings) && (
<div>
{importance?.map((issues) => (
<span
className={styles.importantItem}
key={issues}
style={{
backgroundColor: importanceSettings.colorMap?.[issues],
}}
>
{issues}
</span>
))}
</div>
)}
</div>
{task?.length > 0 && !isEmpty(taskSettings) && (
<div className={styles.taskInfo}>
<div className={styles.taskTitle}>{taskSettings.taskTitle}</div>
<div className={styles.taskList}>
{task?.map((task: any, index: number) => {
const taskTime = get(task, taskSettings.fields?.time);
const { url } = task;
return (
<div
className={classNames(styles.taskItem, {
[styles.taskLinkItem]: url,
})}
key={index}
onClick={(e) => {
url && window.open(url, "_blank");
}}
>
<div
className={styles.taskItemColor}
style={{
backgroundColor:
taskSettings.colorMap?.[
get(task, taskSettings.fields?.priority)
],
}}
></div>
{taskTime && (
<div className={styles.taskItemTime}>
{moment(taskTime).format("YYYY-MM-DD HH:mm")}
</div>
)}
<div className={styles.taskItemText}>
{get(task, taskSettings.fields?.summary)}
</div>
</div>
);
})}
</div>
</div>
)}
</div>
);
}, [importanceSettings, selectedData, taskSettings, footerStyle]);
const onSelect = useCallback(
(date: Moment) => {
const formatDate = date.format("YYYY-MM-DD");
const curBriefData = briefDataMap?.[formatDate];
const curTaskData = taskDataMap?.[formatDate];
const curImportantData = importantDataMap?.[formatDate];
const curData = {
brief: curBriefData,
task: curTaskData,
importance: curImportantData,
};
setSelectedData({ date, data: curData });
onDateSelect({
date: formatDate,
data: curData,
});
},
[briefDataMap, importantDataMap, onDateSelect, taskDataMap]
);
const onPanelChange = useCallback(
(date: Moment, mode: string) => {
const formatDate = date.format("YYYY-MM-DD");
onPickerPanelChange({ mode, date: formatDate });
},
[onPickerPanelChange]
);
return (
<div className={styles.taskCalendar}>
<Calendar
dateFullCellRender={dateRender}
onSelect={onSelect}
onPanelChange={onPanelChange}
defaultValue={pickerValue}
panelMode={mode}
/>
{extraFooterNode}
</div>
);
}
Example #11
Source File: calendar.tsx From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
Calendar: React.FC<CalendarProps> = React.memo(
({
dateSetup,
locale,
viewMode,
rtl,
width,
height,
columnWidth,
horizontalRange,
fontFamily,
fontSize,
highlightRange,
displayWidth,
scrollX,
setScrollX,
svgWidth,
mousePos,
}) => {
const today = new Date();
const getCalendarValuesForMonth = () => {
const topValues: ReactChild[] = [];
const bottomValues: ReactChild[] = [];
const topDefaultHeight = height * 0.5;
for (let i = 0; i < dateSetup.dates.length; i++) {
const date = dateSetup.dates[i];
const bottomValue = getLocaleMonth(date, locale);
bottomValues.push(
<text
key={bottomValue + date.getFullYear()}
y={height * 0.8}
x={columnWidth * i + columnWidth * 0.5}
className={'erda-gantt-calendar-bottom-text'}
>
{bottomValue}
</text>,
);
if (i === 0 || date.getFullYear() !== dateSetup.dates[i - 1].getFullYear()) {
const topValue = date.getFullYear().toString();
let xText: number;
if (rtl) {
xText = (6 + i + date.getMonth() + 1) * columnWidth;
} else {
xText = (6 + i - date.getMonth()) * columnWidth;
}
topValues.push(
<TopPartOfCalendar
key={topValue}
value={topValue}
x1Line={columnWidth * i}
y1Line={0}
y2Line={topDefaultHeight}
xText={xText}
yText={topDefaultHeight * 0.9}
/>,
);
}
}
return [topValues, bottomValues];
};
const getCalendarValuesForWeek = () => {
const topValues: ReactChild[] = [];
const bottomValues: ReactChild[] = [];
let weeksCount = 1;
const topDefaultHeight = height * 0.5;
const { dates } = dateSetup;
for (let i = dates.length - 1; i >= 0; i--) {
const date = dates[i];
let topValue = '';
if (i === 0 || date.getMonth() !== dates[i - 1].getMonth()) {
// top
topValue = `${getLocaleMonth(date, locale)}, ${date.getFullYear()}`;
}
// bottom
const bottomValue = `W${getWeekNumberISO8601(date)}`;
bottomValues.push(
<text
key={date.getTime()}
y={height * 0.8}
x={columnWidth * (i + +rtl)}
className={'erda-gantt-calendar-bottom-text'}
>
{bottomValue}
</text>,
);
if (topValue) {
// if last day is new month
if (i !== dates.length - 1) {
topValues.push(
<TopPartOfCalendar
key={topValue}
value={topValue}
x1Line={columnWidth * i + weeksCount * columnWidth}
y1Line={0}
y2Line={topDefaultHeight}
xText={columnWidth * i + columnWidth * weeksCount * 0.5}
yText={topDefaultHeight * 0.9}
/>,
);
}
weeksCount = 0;
}
weeksCount++;
}
return [topValues, bottomValues];
};
const reHighlightRange = {
...highlightRange,
...(highlightRange?.id && !highlightRange.start && !highlightRange.end ? { x1: -1, x2: -1 } : {}),
};
const HoverBar = ({ style }: { style: Obj }) =>
highlightRange ? (
<div
className="absolute rounded bg-black-06"
style={{
width: Math.abs(reHighlightRange.x2 - reHighlightRange.x1),
height: 40,
left: min([reHighlightRange.x1, reHighlightRange.x2]),
top: 26,
...style,
}}
/>
) : null;
const HoverTime = ({ style }: { style: Obj }) =>
mousePos ? (
<div
className="absolute rounded bg-black-06"
style={{
width: columnWidth,
height: 40,
left: mousePos[0] * columnWidth,
top: 26,
...style,
}}
/>
) : null;
const onChangeScrollX = (direction: number) => {
const moveLen = Math.floor(displayWidth / columnWidth) - 4; // less then display count;
const moveX = moveLen > 0 ? moveLen * columnWidth : columnWidth;
if (direction === -1) {
setScrollX((prevX) => (moveX >= prevX ? -1 : prevX - moveX));
} else if (direction === 1) {
setScrollX((prevX) => (moveX + prevX + displayWidth >= svgWidth ? svgWidth - displayWidth : prevX + moveX));
}
};
const getCalendarValuesForDay = () => {
let bottomValues: React.ReactNode = null;
const dates = dateSetup.dates.slice(...horizontalRange);
const dateInWeeks = [];
// append date when screen have more space
if (!dates.length) return null;
let appendDateLength = Math.max(0, horizontalRange[1] - horizontalRange[0] - dates.length);
while (appendDateLength-- > 0) {
const lastDayInLastWeek = dates[dates.length - 1];
dates.push(addToDate(lastDayInLastWeek, 1, 'day'));
}
const firstDay = dates[0];
const firstDayInWeek = firstDay.getDay();
// use Monday as first day of week
const firstWeek = dates.splice(0, firstDayInWeek === 0 ? 1 : 7 - firstDayInWeek + 1);
while (firstWeek.length < 7) {
const firstDayInFirstWeek = firstWeek[0];
firstWeek.unshift(addToDate(firstDayInFirstWeek, -1, 'day'));
}
dateInWeeks.push(firstWeek);
while (dates.length) {
dateInWeeks.push(dates.splice(0, 7));
}
const lastWeek = dateInWeeks[dateInWeeks.length - 1];
while (lastWeek.length < 7) {
const lastDayInLastWeek = lastWeek[lastWeek.length - 1];
lastWeek.push(addToDate(lastDayInLastWeek, 1, 'day'));
}
const offsetX = (firstDayInWeek ? firstDayInWeek - 1 : 6) * columnWidth;
bottomValues = (
<div
className="flex h-full w-full erda-gantt-calendar-header-container"
style={{ transform: `translateX(${-offsetX}px)` }}
>
{<HoverBar style={{ transform: `translateX(${offsetX}px)` }} />}
{<HoverTime style={{ transform: `translateX(${offsetX}px)` }} />}
{flatten(dateInWeeks).map((day, idx) => {
const mark =
reHighlightRange?.x1 === columnWidth * idx - offsetX ||
reHighlightRange?.x2 === columnWidth * (idx + 1) - offsetX;
const cls = `${
mark
? 'calendar-highlight-text'
: `${[0, 6].includes(day.getDay()) ? 'calendar-disabled-text' : 'calendar-normal-text'}`
}`;
const isStartPos = columnWidth * idx - offsetX === 0;
const isToday = moment(day).isSame(today, 'day');
return (
<div
key={day.getTime()}
style={{
width: columnWidth,
height: 40,
top: 28,
left: columnWidth * idx,
}}
className={`absolute flex flex-col items-center text-xs justify-center ${cls} ${
isToday ? 'text-red' : ''
}`}
>
<span>{Days[day.getDay()]}</span>
<span>{day.getDate()}</span>
{isStartPos || day.getDate() === 1 ? (
<div className="absolute text-default-8 font-medium " style={{ top: -16 }}>
{Months[day.getMonth()]}
</div>
) : null}
{isToday ? (
<div
style={{ left: (columnWidth + 22) / 2, bottom: -14 }}
className="absolute erda-gantt-calendar-today flex justify-center"
>
<div>{i18n.t('dop:Today')}</div>
</div>
) : null}
</div>
);
})}
{scrollX > 0 ? (
<div
className="flex items-center erda-gantt-calendar-arrow-left"
onClick={() => onChangeScrollX(-1)}
style={{ left: offsetX }}
>
<ErdaIcon type="zuofan" className="ml-1" size={10} />
</div>
) : null}
{displayWidth + scrollX < svgWidth ? (
<div
className="flex items-center erda-gantt-calendar-arrow-right"
onClick={() => onChangeScrollX(1)}
style={{ left: offsetX + displayWidth - 16 }}
>
<ErdaIcon type="youfan" className="ml-1" size={10} />
</div>
) : null}
</div>
);
return bottomValues;
};
const getCalendarValuesForOther = () => {
const topValues: ReactChild[] = [];
const bottomValues: ReactChild[] = [];
const ticks = viewMode === ViewMode.HalfDay ? 2 : 4;
const topDefaultHeight = height * 0.5;
const { dates } = dateSetup;
for (let i = 0; i < dates.length; i++) {
const date = dates[i];
const bottomValue = getCachedDateTimeFormat(locale, {
hour: 'numeric',
}).format(date);
bottomValues.push(
<text
key={date.getTime()}
y={height * 0.8}
x={columnWidth * (i + +rtl)}
className={'erda-gantt-calendar-bottom-text'}
fontFamily={fontFamily}
>
{bottomValue}
</text>,
);
if (i === 0 || date.getDate() !== dates[i - 1].getDate()) {
const topValue = `${date.getDate()} ${getLocaleMonth(date, locale)}`;
topValues.push(
<TopPartOfCalendar
key={topValue + date.getFullYear()}
value={topValue}
x1Line={columnWidth * i + ticks * columnWidth}
y1Line={0}
y2Line={topDefaultHeight}
xText={columnWidth * i + ticks * columnWidth * 0.5}
yText={topDefaultHeight * 0.9}
/>,
);
}
}
return [topValues, bottomValues];
};
// let topValues: ReactChild[] = [];
// let bottomValues: ReactChild[] = [];
// switch (dateSetup.viewMode) {
// // case ViewMode.Month:
// // [topValues, bottomValues] = getCalendarValuesForMonth();
// // break;
// // case ViewMode.Week:
// // [topValues, bottomValues] = getCalendarValuesForWeek();
// // break;
// case ViewMode.Day:
// [topValues, bottomValues] = getCalendarValuesForDay();
// break;
// default:
// [topValues, bottomValues] = getCalendarValuesForOther();
// break;
// }
const finalWidth = max([columnWidth * dateSetup.dates.length, width]);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
className="overflow-visible"
width={width}
height={height}
fontFamily={fontFamily}
>
<g className="erda-gantt-calendar" fontSize={fontSize}>
<rect x={0} y={0} width={finalWidth} height={height} className={'erda-gantt-calendar-header'} />
<foreignObject
x={0}
y={0}
width={finalWidth}
height={height}
className={'erda-gantt-calendar-header overflow-visible'}
>
{getCalendarValuesForDay()}
</foreignObject>
{/* {topValues} */}
</g>
</svg>
);
},
)
Example #12
Source File: grid-body.tsx From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
GridBody: React.FC<GridBodyProps> = ({
tasks: originTasks,
dates,
barTasks: tasks,
rowHeight,
svgWidth,
columnWidth,
todayColor,
selectedTask,
ganttHeight,
setSelectedTask,
rtl,
onDateChange,
ganttEvent,
setRangeAddTime,
horizontalRange,
displayWidth,
onMouseMove: propsOnMouseMove,
mouseUnFocus: propsMouseUnFocus,
mousePos,
}) => {
let y = 0;
const gridRows: ReactChild[] = [];
const today = new Date();
const dateDelta =
dates[1].getTime() -
dates[0].getTime() -
dates[1].getTimezoneOffset() * 60 * 1000 +
dates[0].getTimezoneOffset() * 60 * 1000;
const [startPos, setStartPos] = React.useState<null | number[]>(null);
const [endPos, setEndPos] = React.useState<null | number[]>(null);
const [chosenTask, setChosenTask] = React.useState<Obj | null>(null);
React.useEffect(() => {
if (startPos && endPos) {
setRangeAddTime({ x1: startPos[0], x2: endPos[0] });
} else {
setRangeAddTime(null);
}
}, [startPos, endPos]);
const onMouseDown = (e: React.MouseEvent) => {
const gridPos = e.currentTarget.getBoundingClientRect();
const clickY = e.clientY - gridPos.y;
const clickPos = Math.floor(clickY / rowHeight);
const curTask = tasks[clickPos];
if (!curTask.start || !curTask.end) {
setSelectedTask(curTask.id);
setChosenTask(curTask);
setStartPos([
Math.floor((e.clientX - gridPos.x) / columnWidth) * columnWidth,
clickPos * rowHeight + 8,
e.clientX - gridPos.x,
]);
}
};
const mouseUnFocus = () => {
propsMouseUnFocus();
setStartPos(null);
setEndPos(null);
setChosenTask(null);
};
const curDates = dates.slice(...horizontalRange);
const todayIndex = findIndex(curDates, (item) => moment(item).isSame(today, 'day'));
const addTime = getDateFormX(startPos?.[0], endPos?.[0], dateDelta, columnWidth, curDates[0]?.getTime());
const onMouseUp = () => {
if (addTime.length && addTime[1] - addTime[0] >= dateDelta * 0.6 && chosenTask) {
onDateChange({ ...chosenTask, start: new Date(addTime[0]), end: new Date(addTime[1]) });
}
mouseUnFocus();
};
const onMouseMove = (e: React.MouseEvent) => {
const gridPos = e.currentTarget.getBoundingClientRect();
propsOnMouseMove(e);
const curEndPod = e.clientX - gridPos.x;
if (startPos) {
setEndPos(
curEndPod - startPos[2] > 10
? [
(Math.floor((e.clientX - gridPos.x + 1) / columnWidth) + 1) * columnWidth,
startPos[1] + rowHeight - 16,
curEndPod,
]
: null,
);
}
};
tasks?.forEach((task: Task, idx: number) => {
const validTask = task.start && task.end;
let PointIcon = null;
if (validTask) {
const displayPos = Math.floor(displayWidth / columnWidth);
if (curDates?.[0] && task.end < curDates[0]) {
PointIcon = (
<div className="text-default-2 hover:text-default-4 erda-gantt-grid-arrow-box flex items-center">
<ErdaIcon className="cursor-pointer " type="zuo" size={20} onClick={() => setSelectedTask(task.id)} />
<div className="erda-gantt-grid-arrow text-default-6">
{moment(task.start).format('MM-DD')} ~ {moment(task.end).format('MM-DD')}
</div>
</div>
);
} else if (curDates?.[displayPos] && task.start > curDates[displayPos]) {
PointIcon = (
<div
className="text-default-2 hover:text-default-4 erda-gantt-grid-arrow-box flex items-center"
style={{ marginLeft: displayWidth - 20 - 80 }}
>
<div className="erda-gantt-grid-arrow text-default-6">
{moment(task.start).format('MM-DD')} ~ {moment(task.end).format('MM-DD')}
</div>
<ErdaIcon className="cursor-pointer" onClick={() => setSelectedTask(task.id)} type="you" size={20} />
</div>
);
}
}
gridRows.push(
<foreignObject key={`Row${task.id}`} x="0" y={y} width={svgWidth} height={rowHeight}>
<div
className={`flex erda-gantt-grid-row h-full ${
selectedTask?.id === task.id ? 'erda-gantt-grid-row-selected' : ''
} ${!validTask ? 'on-add' : ''} ${mousePos?.[1] === idx ? 'on-hover' : ''}`}
/>
</foreignObject>,
);
y += rowHeight;
});
const { changedTask } = ganttEvent || {};
const realHeight = tasks.length * rowHeight;
const getAddRangePos = () => {
if (startPos && endPos) {
return {
transform: `translate(${min([startPos[0], endPos[0]])},${min([startPos[1], endPos[1]])})`,
width: Math.abs(startPos[0] - endPos[0]),
height: Math.abs(startPos[1] - endPos[1]),
};
}
return null;
};
const getRangePos = () => {
if (changedTask) {
return {
transform: `translate(${changedTask.x1},0)`,
width: changedTask.x2 - changedTask.x1,
height: max([ganttHeight, realHeight]),
};
} else if (startPos && endPos) {
return {
transform: `translate(${min([startPos[0], endPos[0]])},0)`,
width: Math.abs(endPos[0] - startPos[0]),
height: max([ganttHeight, realHeight]),
};
}
return null;
};
const getMouseBlockPos = () => {
if (mousePos) {
const curTask = tasks[mousePos[1]];
if (curTask && !curTask.start && !curTask.end) {
return {
width: columnWidth,
height: rowHeight - 16,
transform: `translate(${mousePos[0] * columnWidth},${mousePos[1] * rowHeight + 8})`,
};
}
}
return null;
};
const getMouseHoverPos = () => {
if (mousePos) {
return {
width: 8,
height: max([ganttHeight, realHeight]),
transform: `translate(${mousePos[0] * columnWidth + columnWidth / 2 - 4},0)`,
};
}
return null;
};
const rangePos = getRangePos();
const mouseBlockPos = getMouseBlockPos();
const addRangePos = getAddRangePos();
const mouseHoverPos = getMouseHoverPos();
const todayStartPos = todayIndex * columnWidth + columnWidth / 2 - 1;
return (
<g
className="gridBody"
onMouseDown={onMouseDown}
onMouseUp={() => {
onMouseUp();
}}
onMouseMove={onMouseMove}
onMouseLeave={mouseUnFocus}
>
{rangePos ? (
<rect {...rangePos} className="erda-gantt-grid-changed-range" />
) : mouseHoverPos ? (
<foreignObject {...mouseHoverPos}>
<div className="h-full w-full erda-gantt-grid-hover-box">
<div className="erda-gantt-grid-hover-arrow" />
<div className="erda-gantt-grid-hover-range h-full w-full" />
</div>
</foreignObject>
) : null}
<g className="rows">{gridRows}</g>
{addRangePos ? (
<g>
<foreignObject {...addRangePos}>
<div className="erda-gantt-grid-add-rect text-sm text-desc bg-white bg-opacity-100 w-full h-full">{`${moment(
addTime[0],
).format('MM-DD')}~${moment(addTime[1]).format('MM-DD')}`}</div>
</foreignObject>
</g>
) : mouseBlockPos ? (
<g>
<foreignObject {...mouseBlockPos}>
<div className="erda-gantt-grid-add-rect bg-white bg-opacity-100 w-full h-full" />
</foreignObject>
</g>
) : null}
{todayIndex > -1 ? (
<polyline
points={`${todayStartPos + columnWidth / 2},4 ${todayStartPos + columnWidth / 2},${max([
ganttHeight,
realHeight,
])}`}
className="erda-gantt-grid-today"
/>
) : null}
</g>
);
}
Example #13
Source File: contextMenuItems.ts From gant-design with MIT License | 4 votes |
gantGetcontextMenuItems = function(
params: GetContextMenuItemsParams,
config: ContextMenuItemsConfig,
) {
const {
downShift,
locale,
onRowsCut,
onRowsPaste,
getContextMenuItems,
defaultJsonParams = {},
hideMenuItemExport,
hideMenuItemExpand,
hiddenMenuItemNames,
suppressRightClickSelected,
showCutChild,
} = config;
const {
context: {
globalEditable,
treeData,
createConfig,
getRowNodeId,
gridManager,
showCut,
rowSelection,
},
node,
api,
} = params;
const exportJson = !isEmpty(defaultJsonParams);
const rowIndex = get(node, 'rowIndex', 0);
let selectedRowNodes: RowNode[] = api.getSelectedNodes();
//右键选中⌚️
if (node && !suppressRightClickSelected) {
const rowNodes = api.getSelectedNodes();
if (!downShift || rowNodes.length == 0) {
node.setSelected(true, true);
selectedRowNodes = [node];
} else {
const rowNodeIndexs = rowNodes.map(rowNode => rowNode.rowIndex);
const maxIndex = max(rowNodeIndexs);
const minIndex = min(rowNodeIndexs);
if (rowIndex >= minIndex && rowIndex <= maxIndex) {
node.setSelected(true, true);
selectedRowNodes = [node];
} else {
const isMin = rowIndex < minIndex;
const nodesCount = isMin ? minIndex - rowIndex : rowIndex - maxIndex;
const startIndex = isMin ? rowIndex : maxIndex + 1;
const extraNodes = Array(nodesCount)
.fill('')
.map((item, index) => {
const startNode = api.getDisplayedRowAtIndex(index + startIndex);
startNode.setSelected(true);
return startNode;
});
selectedRowNodes = isMin ? [...extraNodes, ...rowNodes] : [...rowNodes, ...extraNodes];
}
}
}
const gridSelectedKeys: string[] = [];
const gridSelectedRows = selectedRowNodes.map(item => {
gridSelectedKeys.push(getRowNodeId(get(item, 'data', {})));
return item.data;
}, []);
const disabledCut = selectedRowNodes.length <= 0 || (treeData && isEmpty(createConfig));
const hasPaste =
selectedRowNodes.length > 1 ||
(treeData && isEmpty(createConfig)) ||
isEmpty(gridManager.cutRows);
let items = getContextMenuItems
? getContextMenuItems({
selectedRows: gridSelectedRows,
selectedKeys: gridSelectedKeys,
selectedRowKeys: gridSelectedKeys,
...params,
} as any)
: [];
if (hiddenMenuItemNames && hiddenMenuItemNames.length) {
remove(items, menuItem => hiddenMenuItemNames.some(menuName => menuName === menuItem.name));
}
let defultMenu = [];
if (treeData && !hideMenuItemExpand) {
defultMenu = ['expandAll', 'contractAll'];
}
defultMenu =
defultMenu.length > 0
? items.length > 0
? [...defultMenu, ...items]
: defultMenu
: [...items];
if (!hideMenuItemExport) {
defultMenu = defultMenu.length > 0 ? [...defultMenu, 'export'] : ['export'];
if (suppressRightClickSelected) {
defultMenu.push({
name: locale.exportSelected,
icon: '<span class="ag-icon ag-icon-save" unselectable="on" role="presentation"></span>',
action: () => {
api.exportDataAsExcel({
onlySelected: true,
});
},
});
}
}
defultMenu = exportJson
? [
...defultMenu,
{
name: locale.exportJson,
action: () => {
const { title = 'gantdGrid', onlySelected } = defaultJsonParams;
let data = [];
if (onlySelected) {
data = api.getSelectedRows();
} else {
api.forEachNode(node => {
if (node.data) data.push(node.data);
});
}
const jsonBlob = new Blob([JSON.stringify(data)], {
type: 'text/plain;charset=utf-8',
});
FileSaver.saveAs(jsonBlob, `${title}.json`);
},
},
]
: defultMenu;
if (!globalEditable) return defultMenu;
defultMenu = exportJson
? [
...defultMenu,
{
name: locale.importJson,
action: () => {
const { coverData } = defaultJsonParams;
const input = document.createElement('input');
input.type = 'file';
input.accept = 'application/json';
input.onchange = (event: any) => {
const [file] = event.target.files;
const reader = new FileReader();
reader.readAsText(file);
reader.onload = function(event: any) {
try {
const update = [],
add = [];
const json = JSON.parse(event.target.result);
if (coverData) {
api.setRowData(json);
gridManager.reset();
return;
}
json.map((itemData: any) => {
const rowNode = api.getRowNode(getRowNodeId(itemData));
if (rowNode && rowNode.data) {
update.push({ ...itemData, ...rowNode.data });
} else add.push(itemData);
});
api.applyTransactionAsync({ update }, () => {
gridManager.create(add);
});
} catch (error) {}
};
};
input.click();
},
},
]
: defultMenu;
const showCutBtns = typeof showCut === 'function' ? showCut(params) : showCut;
const editMenu = [...defultMenu];
if (showCutBtns) {
editMenu.push(
...[
{
name: locale.cutRows,
disabled: disabledCut,
action: params => {
try {
const canPut = onRowsCut ? onRowsCut(selectedRowNodes) : true;
return canPut && gridManager.cut(selectedRowNodes);
} catch (error) {}
},
},
{
name: locale.cancelCut,
disabled: isEmpty(gridManager.cutRows),
action: params => {
try {
gridManager.cancelCut();
} catch (error) {}
},
},
{
name: locale.pasteTop,
disabled: hasPaste,
action: params => {
const [rowNode] = selectedRowNodes;
const canPaste = onRowsPaste ? onRowsPaste(gridManager.cutRows, rowNode) : true;
canPaste && gridManager.paste(rowNode);
},
},
{
name: locale.pasteBottom,
disabled: hasPaste,
action: params => {
const [rowNode] = selectedRowNodes;
const canPaste = onRowsPaste ? onRowsPaste(gridManager.cutRows, rowNode) : true;
canPaste && gridManager.paste(rowNode, false);
},
},
],
);
if (showCutChild)
editMenu.push({
name: locale.pasteChild,
disabled: hasPaste,
action: params => {
const [rowNode] = selectedRowNodes;
const canPaste = onRowsPaste ? onRowsPaste(gridManager.cutRows, rowNode) : true;
canPaste && gridManager.paste(rowNode, false, true);
},
});
}
return editMenu;
}