mirror of
https://github.com/LucasVbr/todo-list.git
synced 2026-05-14 01:32:02 +00:00
Rebuild the app
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 LucasVbr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,6 +1,6 @@
|
||||
# TodoList
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.1.0.
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.1.2.
|
||||
|
||||
## Development server
|
||||
|
||||
|
||||
+3
-10
@@ -5,11 +5,7 @@
|
||||
"projects": {
|
||||
"todo-list": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
"schematics": {},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
@@ -22,15 +18,13 @@
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/font-awesome/scss/font-awesome.scss",
|
||||
"node_modules/bulma/bulma.sass",
|
||||
"src/styles.scss"
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
@@ -92,13 +86,12 @@
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
|
||||
Generated
+385
-355
File diff suppressed because it is too large
Load Diff
+2
-3
@@ -19,14 +19,13 @@
|
||||
"@angular/platform-browser-dynamic": "^14.1.0",
|
||||
"@angular/router": "^14.1.0",
|
||||
"bulma": "^0.9.4",
|
||||
"font-awesome": "^4.7.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^14.1.0",
|
||||
"@angular/cli": "~14.1.0",
|
||||
"@angular-devkit/build-angular": "^14.1.2",
|
||||
"@angular/cli": "~14.1.2",
|
||||
"@angular/compiler-cli": "^14.1.0",
|
||||
"@types/jasmine": "~4.0.0",
|
||||
"jasmine-core": "~4.2.0",
|
||||
|
||||
+23
-34
@@ -1,40 +1,29 @@
|
||||
<div class="container">
|
||||
<div class="card p-6 mt-6">
|
||||
<h1 class="title has-text-centered">{{ title }}</h1>
|
||||
<h1 class="title has-text-centered mt-5">{{ title }}</h1>
|
||||
|
||||
<!-- Todolist -->
|
||||
<div class="m-5">
|
||||
<div *ngIf="list.length == 0">
|
||||
<p class="empty-list subtitle has-text-centered">Empty list</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<table class="table is-striped is-narrow is-fullwidth">
|
||||
<tr *ngFor="let todoItem of todoList">
|
||||
<td>
|
||||
<input class="checkbox is-primary" type="checkbox" (change)="saveList()"
|
||||
[checked]="todoItem.completed" name="task-{{ todoItem.id }}"
|
||||
id="task-{{ todoItem.id }}">
|
||||
</td>
|
||||
<td>
|
||||
<label for="task-{{ todoItem.id }}">{{ todoItem.task }}</label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="button is-danger is-primary is-pulled-right" type="button"
|
||||
value="remove" (click)="removeItem(todoItem.id)">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="columns" *ngFor="let item of list">
|
||||
<input type="checkbox" [(ngModel)]="item.checked" (ngModelChange)="saveList()" name="{{ item.text }}" id="{{ item.text }}">
|
||||
<label class="checkbox pl-2" for="{{ item.text }}">
|
||||
{{ item.text }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Input -->
|
||||
<div class="columns is-multiline">
|
||||
<div class="column">
|
||||
<input class="input" type="text" [(ngModel)]="inputValue" (keydown.enter)="addItem()">
|
||||
</div>
|
||||
<div class="column is-2">
|
||||
<button class="button is-primary" (click)="addItem()">
|
||||
<span class="icon">
|
||||
<i class="fa fa-plus"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="column is-2">
|
||||
<button class="button is-danger" (click)="removeCheckedItems()">
|
||||
<span class="icon">
|
||||
<i class="fa fa-trash"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<input class="input is-primary" type="text" [(ngModel)]="todoInput"
|
||||
(keydown.enter)="addItem()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
input[type=checkbox] + label {
|
||||
transition: all 500ms;
|
||||
}
|
||||
|
||||
input[type=checkbox]:checked + label {
|
||||
text-decoration: line-through;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
}
|
||||
+38
-37
@@ -1,56 +1,57 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import TodoItem from "../models/todo-item.model";
|
||||
import LocalService from "../services/local.service";
|
||||
import TodoItem from '../models/TodoItem';
|
||||
|
||||
const LOCAL_STORAGE_KEY: string = "todoList";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
export class AppComponent implements OnInit{
|
||||
public title = 'Todo List App';
|
||||
public list: TodoItem[] = [];
|
||||
public todoInput!: string;
|
||||
public todoList!: TodoItem[];
|
||||
|
||||
private LOCAL_STORAGE_KEY = "todoList";
|
||||
inputValue: any;
|
||||
|
||||
ngOnInit(): void {
|
||||
const savedData: null | TodoItem[] = LocalService.getData(this.LOCAL_STORAGE_KEY)
|
||||
if (savedData) this.list = savedData;
|
||||
ngOnInit() {
|
||||
this.todoInput = "";
|
||||
this.todoList = this.getSavedList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new item if input is not empty and the item doesn't exist already
|
||||
*/
|
||||
addItem(): void {
|
||||
const listOfTodoText = this.list.map(item => item.text);
|
||||
private getSavedList(): TodoItem[] {
|
||||
console.info("Load TodoList");
|
||||
|
||||
if (this.inputValue && !listOfTodoText.includes(this.inputValue)) {
|
||||
this.list.push(new TodoItem(this.inputValue))
|
||||
this.inputValue = "";
|
||||
this.saveList()
|
||||
}
|
||||
const loadedValues: string|null = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
|
||||
if (loadedValues) return JSON.parse(loadedValues) as TodoItem[];
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a specific item of the list
|
||||
* @param toRemove TodoItem to remove
|
||||
*/
|
||||
removeItem(toRemove: TodoItem): void {
|
||||
this.list = this.list.filter(item => item !== toRemove);
|
||||
this.saveList()
|
||||
public saveList() {
|
||||
console.info("Save todoList");
|
||||
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.todoList))
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all checked items of the list
|
||||
*/
|
||||
removeCheckedItems(): void {
|
||||
this.list = this.list.filter(item => !item.checked)
|
||||
this.saveList()
|
||||
public addItem(): void {
|
||||
if (!this.todoInput) return;
|
||||
|
||||
const newItem: TodoItem = new TodoItem(this.getNextIndex(), this.todoInput);
|
||||
this.todoList.push(newItem);
|
||||
this.todoInput = "";
|
||||
|
||||
this.saveList();
|
||||
}
|
||||
|
||||
saveList(): void {
|
||||
LocalService.saveData(this.LOCAL_STORAGE_KEY, this.list);
|
||||
console.log(this.list)
|
||||
public removeItem(index: number): void {
|
||||
this.todoList = this.todoList.filter(item => {
|
||||
return item.id !== index;
|
||||
});
|
||||
this.saveList();
|
||||
}
|
||||
|
||||
private getNextIndex() {
|
||||
if (this.todoList.length === 0) return 1;
|
||||
return Math.max(...this.todoList.map(item => item.id)) + 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -10,7 +10,7 @@ import {FormsModule} from "@angular/forms";
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule
|
||||
FormsModule,
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export default class TodoItem {
|
||||
public completed: boolean;
|
||||
|
||||
constructor(public id: number, public task: string) {
|
||||
this.completed = false;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export default class TodoItem {
|
||||
|
||||
constructor(
|
||||
public text: string,
|
||||
public checked: boolean = false
|
||||
) {}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import TodoItem from "../models/todo-item.model";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export default class LocalService {
|
||||
|
||||
static saveData(key: string, data: TodoItem[]) {
|
||||
localStorage.setItem(key, JSON.stringify(data));
|
||||
}
|
||||
|
||||
static getData(key: string): TodoItem[] | null {
|
||||
const data = localStorage.getItem(key);
|
||||
if (!data) return null
|
||||
|
||||
return JSON.parse(data) as TodoItem[];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
@@ -1,9 +0,0 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
body {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background-color: whitesmoke;
|
||||
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
Reference in New Issue
Block a user