Issue
I want to get this effect after clicking the save button for example:
"timeTable":{
"0": [{"from":"08:00","to":"12:00"}, {"from":"14:00","to":"18:20"}],
"1": [{"from":"08:00","to":"16:00"}]
.....
}
Unfortunately, I can not do this, please help. The result is: for example:
{"0":{
"0":{"from":"00:00","to":"23:00"}},
"1":{"0":{"from":"08:00","to":"16:00"}}}
}
I don't know how to rewrite the getTimeline function... https://stackblitz.com/edit/angular-ivy-slrmqc?fbclid=IwAR3mZbHjz8TkLUZJI1kd7gsMnaPikdS0eyGzdF17RPYJ70jyHhXMOzW8x3w&file=src%2Fapp%2Fapp.component.ts
import { Component, OnInit, VERSION } from '@angular/core';
interface Row {
name: string;
items: number[];
active: boolean;
day: number;
}
interface HourScheduleDefinitionModel {
from: string;
to: string;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
arr: Row[] = [
{ name: 'Monday', day: 0, items: new Array(24).fill(1), active: true },
{ name: 'Tuesday', day: 1, items: new Array(24).fill(0), active: false },
{
name: 'Wednesday',
day: 2,
items: new Array(24).fill(0),
active: false,
},
{ name: 'Thursday', day: 3, items: new Array(24).fill(0), active: false },
{ name: 'Friday', day: 4, items: new Array(24).fill(0), active: false },
{ name: 'Saturday', day: 5, items: new Array(24).fill(0), active: false },
{ name: 'Sunday', day: 6, items: new Array(24).fill(0), active: false },
];
timeTable2: Map<number, Array<HourScheduleDefinitionModel>>;
timeTable: HourScheduleDefinitionModel[][];
// for example
// "timeTable":{
// "0": [{"from":"08:00","to":"12:00"}, {"from":"14:00","to":"18:00"}],
// "1": [{"from":"08:00","to":"16:00"}]
// }
ngOnInit() {
this.arr.forEach((row: Row, index: number) => {
if (this.arr[index].items.every((col) => col === 1)) {
row.active = true;
}
});
}
click(day: number, range: number) {
this.arr[day].items[range] = this.arr[day].items[range] === 1 ? 0 : 1;
this.arr[day].active = this.arr[day].items.every((col) => col === 1);
}
toggleRow(day: number): void {
this.arr[day].items.fill(this.arr[day].active ? 0 : 1);
this.arr[day].active = !this.arr[day].active;
}
getTimeline = () => {
const result = [];
console.log(this.arr);
for (const item of this.arr) {
let start = -1,
timeTable = [];
for (let i = 0; i < item.items.length; i++) {
if (item.items[i] === 1) {
if (start === -1) {
start = i;
}
} else {
if (start !== -1) {
timeTable.push({
from: start < 10 ? '0' + start + ':00' : start + ':00',
to: i < 10 ? '0' + (i - 1) + ':00' : i - 1 + ':00',
});
start = -1;
}
}
if (start !== -1 && i === item.items.length - 1) {
timeTable.push({
from: start < 10 ? '0' + start + ':00' : start + ':00',
to: '23:00',
});
}
}
// if(timeTable.length){
result.push({
// day: item.day,
...timeTable,
});
// }
}
return result;
};
save() {
this.timeTable = this.getTimeline();
console.log(this.timeTable);
let val = { ...this.timeTable };
console.log(JSON.stringify(val));
}
}
Solution
How about something like this?
// The Row interface as you defined it
interface Row {
name: string;
items: number[];
active: boolean;
day: number;
}
// The dummy data you provided
const arr: Row[] = [
{ name: 'Monday', day: 0, items: new Array(24).fill(1), active: true },
{ name: 'Tuesday', day: 1, items: new Array(24).fill(0), active: false },
{ name: 'Wednesday', day: 2, items: new Array(24).fill(0), active: false },
{ name: 'Thursday', day: 3, items: new Array(24).fill(0), active: false },
{ name: 'Friday', day: 4, items: new Array(24).fill(0), active: false },
{ name: 'Saturday', day: 5, items: new Array(24).fill(0), active: false },
{ name: 'Sunday', day: 6, items: new Array(24).fill(0), active: false },
];
// An interface to describe the concept of a period (e.g. {"from":"08:00","to":"12:00"})
interface Period {
from: string;
to: string;
}
// A function to convert an array of 24 numbers into an array of Periods
const getPeriodsForDay = (items: number[]): Period[] => {
const result: Period[] = [];
let i = 0;
let periodStartIndex: number | null = null;
let isCurrentIndexActive = false;
while (i < items.length) {
isCurrentIndexActive = items[i] === 1;
if (isCurrentIndexActive && periodStartIndex == null)
{
periodStartIndex = i;
} else if (!isCurrentIndexActive && periodStartIndex != null) {
result.push({ from: convertToTimeString(periodStartIndex), to: convertToTimeString(i) });
}
i++;
}
if (isCurrentIndexActive && periodStartIndex != null) {
result.push({ from: convertToTimeString(periodStartIndex), to: convertToTimeString(i - 1) });
}
return result;
}
// Utility function to transform an index into your desired string (e.g. 3 would become "03:00")
const convertToTimeString = (index: number) => {
return `${index.toString().padStart(2, "0")}:00`
};
// A function to create the wrapper around the result
const getTimeTable = (rows: Row[]) => {
const timeTable: { [key: string]: Period[] } = {};
for(let i = 0; i < rows.length; i++) {
timeTable[i] = getPeriodsForDay(rows[i].items);
}
return {
timeTable: timeTable
}
};
console.log(getTimeTable(arr));
See Typescript Playground here
Answered By - Stanislas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.