Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zzha zzha
OpenXG-RAN
Commits
51362d9c
Commit
51362d9c
authored
Mar 14, 2022
by
El Mghazli Yacine
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial commit
parent
8ead6ae7
Changes
55
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
55 changed files
with
318 additions
and
2809 deletions
+318
-2809
ngx/.eslintrc.json
ngx/.eslintrc.json
+2
-2
ngx/.gitignore
ngx/.gitignore
+2
-0
ngx/package-lock.json
ngx/package-lock.json
+103
-104
ngx/src/app/api/autosend.api.ts
ngx/src/app/api/autosend.api.ts
+0
-23
ngx/src/app/api/bookings.api.ts
ngx/src/app/api/bookings.api.ts
+0
-80
ngx/src/app/api/commands.api.ts
ngx/src/app/api/commands.api.ts
+37
-0
ngx/src/app/api/reports.api.ts
ngx/src/app/api/reports.api.ts
+0
-32
ngx/src/app/api/users.api.ts
ngx/src/app/api/users.api.ts
+0
-64
ngx/src/app/app-routing.module.ts
ngx/src/app/app-routing.module.ts
+2
-13
ngx/src/app/app.module.ts
ngx/src/app/app.module.ts
+12
-41
ngx/src/app/components/bookings/bookings.component.html
ngx/src/app/components/bookings/bookings.component.html
+0
-226
ngx/src/app/components/bookings/bookings.component.ts
ngx/src/app/components/bookings/bookings.component.ts
+0
-167
ngx/src/app/components/callback/callback.component.css
ngx/src/app/components/callback/callback.component.css
+0
-0
ngx/src/app/components/callback/callback.component.html
ngx/src/app/components/callback/callback.component.html
+0
-1
ngx/src/app/components/callback/callback.component.ts
ngx/src/app/components/callback/callback.component.ts
+0
-15
ngx/src/app/components/cleaners/cleaners.component.css
ngx/src/app/components/cleaners/cleaners.component.css
+0
-35
ngx/src/app/components/cleaners/cleaners.component.html
ngx/src/app/components/cleaners/cleaners.component.html
+0
-49
ngx/src/app/components/cleaners/cleaners.component.ts
ngx/src/app/components/cleaners/cleaners.component.ts
+0
-70
ngx/src/app/components/commands/commands.component.css
ngx/src/app/components/commands/commands.component.css
+0
-0
ngx/src/app/components/commands/commands.component.html
ngx/src/app/components/commands/commands.component.html
+8
-0
ngx/src/app/components/commands/commands.component.ts
ngx/src/app/components/commands/commands.component.ts
+40
-0
ngx/src/app/components/messages/messages.component.css
ngx/src/app/components/messages/messages.component.css
+0
-35
ngx/src/app/components/messages/messages.component.html
ngx/src/app/components/messages/messages.component.html
+0
-80
ngx/src/app/components/messages/messages.component.ts
ngx/src/app/components/messages/messages.component.ts
+0
-30
ngx/src/app/components/nav/nav.component.html
ngx/src/app/components/nav/nav.component.html
+5
-18
ngx/src/app/components/nav/nav.component.ts
ngx/src/app/components/nav/nav.component.ts
+2
-3
ngx/src/app/components/new-booking-dialog/new-booking.component.html
.../components/new-booking-dialog/new-booking.component.html
+0
-39
ngx/src/app/components/new-booking-dialog/new-booking.component.ts
...pp/components/new-booking-dialog/new-booking.component.ts
+0
-42
ngx/src/app/components/new-cleaner-dialog/new-cleaner.component.html
.../components/new-cleaner-dialog/new-cleaner.component.html
+0
-22
ngx/src/app/components/new-cleaner-dialog/new-cleaner.component.ts
...pp/components/new-cleaner-dialog/new-cleaner.component.ts
+0
-15
ngx/src/app/components/user/user.component.css
ngx/src/app/components/user/user.component.css
+0
-35
ngx/src/app/components/user/user.component.html
ngx/src/app/components/user/user.component.html
+0
-108
ngx/src/app/components/user/user.component.ts
ngx/src/app/components/user/user.component.ts
+0
-32
ngx/src/app/components/year/year.component.css
ngx/src/app/components/year/year.component.css
+0
-34
ngx/src/app/components/year/year.component.html
ngx/src/app/components/year/year.component.html
+0
-171
ngx/src/app/components/year/year.component.ts
ngx/src/app/components/year/year.component.ts
+0
-140
ngx/src/app/controls/booking.control.ts
ngx/src/app/controls/booking.control.ts
+0
-88
ngx/src/app/controls/calendar.control.ts
ngx/src/app/controls/calendar.control.ts
+0
-47
ngx/src/app/controls/cleaner.control.ts
ngx/src/app/controls/cleaner.control.ts
+0
-90
ngx/src/app/controls/cleaning.control.ts
ngx/src/app/controls/cleaning.control.ts
+0
-46
ngx/src/app/controls/command.control.ts
ngx/src/app/controls/command.control.ts
+46
-0
ngx/src/app/controls/guest.control.ts
ngx/src/app/controls/guest.control.ts
+0
-52
ngx/src/app/controls/message.control.ts
ngx/src/app/controls/message.control.ts
+0
-50
ngx/src/app/controls/newbooking.control.ts
ngx/src/app/controls/newbooking.control.ts
+0
-89
ngx/src/app/controls/option.control.ts
ngx/src/app/controls/option.control.ts
+57
-0
ngx/src/app/controls/range.control.ts
ngx/src/app/controls/range.control.ts
+0
-89
ngx/src/app/controls/user.control.ts
ngx/src/app/controls/user.control.ts
+0
-188
ngx/src/app/guards/auth.guard.ts
ngx/src/app/guards/auth.guard.ts
+0
-16
ngx/src/app/interceptors/interceptors.ts
ngx/src/app/interceptors/interceptors.ts
+0
-2
ngx/src/app/interceptors/token.interceptor.ts
ngx/src/app/interceptors/token.interceptor.ts
+0
-31
ngx/src/app/services/dialog.service.ts
ngx/src/app/services/dialog.service.ts
+0
-20
ngx/src/app/services/user.service.ts
ngx/src/app/services/user.service.ts
+0
-156
ngx/src/app/services/worker.service.ts
ngx/src/app/services/worker.service.ts
+0
-114
ngx/src/environments/environment.prod.ts
ngx/src/environments/environment.prod.ts
+1
-3
ngx/src/environments/environment.ts
ngx/src/environments/environment.ts
+1
-2
No files found.
ngx/.eslintrc.json
View file @
51362d9c
...
...
@@ -10,7 +10,7 @@
],
"parserOptions"
:
{
"project"
:
[
"tsconfig.json"
"
ngx/
tsconfig.json"
],
"createDefaultProgram"
:
true
},
...
...
@@ -47,4 +47,4 @@
"rules"
:
{}
}
]
}
}
\ No newline at end of file
ngx/.gitignore
View file @
51362d9c
...
...
@@ -47,3 +47,5 @@ testem.log
.DS_Store
Thumbs.db
config.toml
/.angular
ngx/package-lock.json
View file @
51362d9c
This diff is collapsed.
Click to expand it.
ngx/src/app/api/autosend.api.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
HttpClient
,
HttpParams
}
from
'
@angular/common/http
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
environment
}
from
'
src/environments/environment
'
;
import
{
IBooking
}
from
'
./bookings.api
'
;
import
{
IUser
}
from
'
./users.api
'
;
const
route
=
'
/autosend
'
;
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
AutoSendApi
{
constructor
(
private
httpClient
:
HttpClient
)
{
}
public
autoSendMyBookings$
=
(
month
:
string
)
=>
this
.
httpClient
.
get
<
IBooking
[]
>
(
environment
.
backend
+
route
+
'
/my/month/
'
+
month
);
public
autoSendUsersBookings$
=
(
month
:
string
)
=>
this
.
httpClient
.
get
<
IBooking
[]
>
(
environment
.
backend
+
route
+
'
/users/month/
'
+
month
);
public
register$
=
(
code
:
string
)
=>
{
const
params
=
new
HttpParams
().
append
(
'
code
'
,
code
);
return
this
.
httpClient
.
post
<
IUser
>
(
environment
.
backend
+
route
,
null
,
{
params
});
}
}
\ No newline at end of file
ngx/src/app/api/bookings.api.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable no-shadow */
/* eslint-disable @typescript-eslint/naming-convention */
import
{
HttpClient
}
from
'
@angular/common/http
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
environment
}
from
'
src/environments/environment
'
;
export
enum
IState
{
BOOKED
=
'
booked
'
,
CHECKIN_HOUR_NOK
=
'
checkin nok
'
,
WAITING_CHECKIN_HOUR
=
'
waiting checkin
'
,
CHECKIN_HOUR_OK
=
'
checkin ok
'
,
INSIDE
=
'
inside
'
,
WAITING_CHECKOUT_HOUR
=
'
waiting checkout
'
,
CHECKOUT_HOUR_OK
=
'
checkout ok
'
,
OUTSIDE
=
'
outside
'
,
TELFORGET
=
'
telforget
'
,
}
export
enum
IPlatform
{
DIRECT
=
'
direct
'
,
AIRBNB
=
'
airbnb
'
,
TRIPADVISOR
=
'
tripadvisor
'
,
BOOKING
=
'
booking
'
,
WIMDU
=
'
wimdu
'
,
BEDYCASA
=
'
bedycasa
'
,
HOUSETRIP
=
'
housetrip
'
,
NINEFLATS
=
'
9flats
'
,
ONLY
=
'
only
'
,
LEBONCOIN
=
'
leboncoin
'
,
SEJOURNING
=
'
sejourning
'
,
WAY2STAY
=
'
waytostay
'
}
export
interface
IRange
{
start
:
string
;
end
:
string
;
}
export
interface
IGuest
{
given
:
string
;
email
:
string
;
}
export
interface
ICleaning
{
cleanerEmail
:
string
;
hours
:
number
;
}
export
interface
INewBooking
{
amount
:
number
;
platform
:
IPlatform
;
range
:
IRange
;
guest
:
IGuest
;
}
export
interface
IBooking
extends
INewBooking
{
month
:
string
;
id
:
string
;
state
:
IState
;
cleaning
?:
ICleaning
;
}
const
route
=
'
/bookings
'
;
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
BookingsApi
{
constructor
(
private
httpClient
:
HttpClient
)
{
}
public
readBookings$
=
(
month
:
string
)
=>
this
.
httpClient
.
get
<
IBooking
[]
>
(
environment
.
backend
+
route
+
'
/month/
'
+
month
);
public
refreshBookings$
=
(
month
:
string
)
=>
this
.
httpClient
.
get
<
IBooking
[]
>
(
environment
.
backend
+
route
+
'
/refresh/
'
+
month
);
public
createBooking$
=
(
booking
:
INewBooking
)
=>
this
.
httpClient
.
post
<
IBooking
>
(
environment
.
backend
+
route
,
booking
);
public
updateBooking$
=
(
booking
:
IBooking
)
=>
this
.
httpClient
.
put
<
string
[]
>
(
environment
.
backend
+
route
,
booking
);
public
readBookingsList$
=
(
ids
:
string
[])
=>
this
.
httpClient
.
put
<
IBooking
[]
>
(
environment
.
backend
+
route
+
'
/list
'
,
ids
);
public
deleteBooking$
=
(
id
:
string
)
=>
this
.
httpClient
.
delete
(
environment
.
backend
+
route
+
'
/
'
+
id
);
}
ngx/src/app/api/commands.api.ts
0 → 100644
View file @
51362d9c
import
{
HttpClient
}
from
'
@angular/common/http
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
environment
}
from
'
src/environments/environment
'
;
export
interface
IOption
{
key
:
string
;
value
:
number
;
}
export
interface
ICommand
{
name
:
string
;
options
:
IOption
[];
}
export
interface
IStatus
{
infos
:
string
;
}
export
interface
ILog
{
text
:
string
;
}
const
route
=
'
/commands
'
;
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
CommandsApi
{
constructor
(
private
httpClient
:
HttpClient
)
{
}
public
readCommands$
=
()
=>
this
.
httpClient
.
get
<
ICommand
[]
>
(
environment
.
backend
+
route
+
'
/list
'
);
public
readStatus$
=
()
=>
this
.
httpClient
.
get
<
IStatus
>
(
environment
.
backend
+
route
+
'
/status
'
);
public
runCommand$
=
(
command
:
ICommand
)
=>
this
.
httpClient
.
post
<
ICommand
>
(
environment
.
backend
+
route
,
command
);
public
readLogs$
=
()
=>
this
.
httpClient
.
get
<
IStatus
>
(
environment
.
backend
+
route
+
'
/logs
'
);
}
\ No newline at end of file
ngx/src/app/api/reports.api.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
HttpClient
}
from
'
@angular/common/http
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
environment
}
from
'
src/environments/environment
'
;
export
interface
IReport
{
month
:
string
;
bookings
:
string
[];
brut
:
number
;
cleanings
:
number
;
nights
:
number
;
occupation
:
number
;
net
:
number
;
nightRate
?:
number
;
netRate
?:
number
;
}
const
route
=
'
/reports
'
;
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
ReportsApi
{
constructor
(
private
httpClient
:
HttpClient
)
{
}
public
readReport$
=
(
month
:
string
)
=>
this
.
httpClient
.
get
<
IReport
>
(
environment
.
backend
+
route
+
'
/month/
'
+
month
);
public
refreshReport$
=
(
month
:
string
)
=>
this
.
httpClient
.
put
<
IReport
>
(
environment
.
backend
+
route
+
'
/month/
'
+
month
,
null
);
public
readReports$
=
(
year
:
string
)
=>
this
.
httpClient
.
get
<
IReport
[]
>
(
environment
.
backend
+
route
+
'
/year/
'
+
year
);
public
refreshReports$
=
(
year
:
string
)
=>
this
.
httpClient
.
put
<
IReport
[]
>
(
environment
.
backend
+
route
+
'
/year/
'
+
year
,
null
);
}
ngx/src/app/api/users.api.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
HttpClient
,
HttpParams
}
from
'
@angular/common/http
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
environment
}
from
'
src/environments/environment
'
;
export
enum
ISubject
{
ALERT
=
'
Alert no email
'
,
GENERAL_INFOS
=
'
Infos
'
,
CHECKIN_METHOD
=
'
Checkin
'
,
CHECKIN_QUESTION
=
'
Checkin question
'
,
WELCOME
=
'
Welcome
'
,
CHECKOUT_METHOD
=
'
Checkout
'
,
CHECKOUT_QUESTION
=
'
Checkout question
'
,
GOODBYE
=
'
Good Bye
'
,
}
export
interface
IMessage
{
subject
:
ISubject
;
body
:
string
;
}
export
interface
ICalendar
{
summary
:
string
;
id
:
string
;
}
export
interface
ICleaner
{
rate
:
number
;
name
:
string
;
email
:
string
;
default
:
boolean
;
}
export
interface
IUser
{
subjectPrefix
:
string
;
defaultCheckInHour
:
number
;
defaultCheckOutHour
:
number
;
defaultCleaningHours
:
number
;
busyCal
:
ICalendar
;
cleaningCal
:
ICalendar
;
reelCal
:
ICalendar
;
address
:
string
;
name
:
string
;
tel
:
string
;
messages
:
IMessage
[];
cleaners
:
ICleaner
[];
isRegistered
:
boolean
;
autoSend
:
boolean
;
}
const
route
=
'
/users
'
;
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
UsersApi
{
constructor
(
private
httpClient
:
HttpClient
)
{
}
public
read$
=
()
=>
this
.
httpClient
.
get
<
IUser
>
(
environment
.
backend
+
route
);
public
refresh$
=
()
=>
this
.
httpClient
.
get
<
IUser
>
(
environment
.
backend
+
route
+
'
/refresh
'
);
public
update$
=
(
user
:
IUser
)
=>
this
.
httpClient
.
put
<
string
[]
>
(
environment
.
backend
+
route
,
user
);
}
ngx/src/app/app-routing.module.ts
View file @
51362d9c
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
Routes
,
RouterModule
}
from
'
@angular/router
'
;
import
{
BookingsComponent
}
from
'
./components/bookings/bookings.component
'
;
import
{
CallbackComponent
}
from
'
./components/callback/callback.component
'
;
import
{
CleanersComponent
}
from
'
./components/cleaners/cleaners.component
'
;
import
{
MessagesComponent
}
from
'
./components/messages/messages.component
'
;
import
{
UserComponent
}
from
'
./components/user/user.component
'
;
import
{
YearComponent
}
from
'
./components/year/year.component
'
;
import
{
AuthGuard
}
from
'
./guards/auth.guard
'
;
import
{
CommandsComponent
}
from
'
./components/commands/commands.component
'
;
const
routes
:
Routes
=
[
{
path
:
''
,
redirectTo
:
'
/
'
,
pathMatch
:
'
full
'
},
{
path
:
'
bookings
'
,
component
:
BookingsComponent
,
canActivate
:
[
AuthGuard
]
},
{
path
:
'
year
'
,
component
:
YearComponent
,
canActivate
:
[
AuthGuard
]
},
{
path
:
'
messages
'
,
component
:
MessagesComponent
,
canActivate
:
[
AuthGuard
]
},
{
path
:
'
cleaners
'
,
component
:
CleanersComponent
,
canActivate
:
[
AuthGuard
]
},
{
path
:
'
user
'
,
component
:
UserComponent
,
canActivate
:
[
AuthGuard
]
},
{
path
:
'
oauth2callback
'
,
component
:
CallbackComponent
},
{
path
:
'
commands
'
,
component
:
CommandsComponent
},
{
path
:
'
**
'
,
redirectTo
:
''
},
];
...
...
ngx/src/app/app.module.ts
View file @
51362d9c
import
{
ClipboardModule
}
from
'
@angular/cdk/clipboard/
'
;
import
{
HttpClientModule
}
from
'
@angular/common/http
'
;
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
AngularFireModule
}
from
'
@angular/fire/compat
'
;
import
{
FlexLayoutModule
}
from
'
@angular/flex-layout
'
;
import
{
ReactiveFormsModule
}
from
'
@angular/forms
'
;
import
{
MatButtonModule
}
from
'
@angular/material/button
'
;
import
{
MatCardModule
}
from
'
@angular/material/card
'
;
import
{
MatChipsModule
}
from
'
@angular/material/chips
'
;
...
...
@@ -20,51 +17,29 @@ import { MatMenuModule } from '@angular/material/menu';
import
{
MatPaginatorModule
}
from
'
@angular/material/paginator
'
;
import
{
MatProgressSpinnerModule
}
from
'
@angular/material/progress-spinner
'
;
import
{
MatSelectModule
}
from
'
@angular/material/select
'
;
import
{
MatSidenavModule
}
from
'
@angular/material/sidenav
'
;
import
{
MatSlideToggleModule
}
from
'
@angular/material/slide-toggle
'
;
import
{
MatSnackBarModule
}
from
'
@angular/material/snack-bar
'
;
import
{
MatTableModule
}
from
'
@angular/material/table
'
;
import
{
MatToolbarModule
}
from
'
@angular/material/toolbar
'
;
import
{
BrowserModule
}
from
'
@angular/platform-browser
'
;
import
{
BrowserAnimationsModule
}
from
'
@angular/platform-browser/animations
'
;
import
{
GoogleApiModule
,
NG_GAPI_CONFIG
}
from
'
ng-gapi
'
;
import
{
NgxMaterialTimepickerModule
}
from
'
ngx-material-timepicker
'
;
import
{
BookingsApi
}
from
'
./api/bookings.api
'
;
import
{
UsersApi
}
from
'
./api/users.api
'
;
import
{
AppRoutingModule
}
from
'
./app-routing.module
'
;
import
{
AppComponent
}
from
'
./app.component
'
;
import
{
BookingsComponent
}
from
'
./components/bookings/bookings.component
'
;
import
{
YearComponent
}
from
'
./components/year/year.component
'
;
import
{
CallbackComponent
}
from
'
./components/callback/callback.component
'
;
import
{
CleanersComponent
}
from
'
./components/cleaners/cleaners.component
'
;
import
{
ErrorDialogComponent
}
from
'
./components/error-dialog/error-dialog.component
'
;
import
{
MessagesComponent
}
from
'
./components/messages/messages.component
'
;
import
{
NavComponent
}
from
'
./components/nav/nav.component
'
;
import
{
NewBookingDialogComponent
}
from
'
./components/new-booking-dialog/new-booking.component
'
;
import
{
NewCleanerDialogComponent
}
from
'
./components/new-cleaner-dialog/new-cleaner.component
'
;
import
{
UserComponent
}
from
'
./components/user/user.component
'
;
import
{
InterceptorProviders
}
from
'
./interceptors/interceptors
'
;
import
{
LoadingService
}
from
'
./services/loading.service
'
;
import
{
FIREBASE
,
UserService
}
from
'
./services/user.service
'
;
import
{
gapiClientConfig
,
WorkerService
}
from
'
./services/worker.service
'
;
import
{
BrowserModule
}
from
'
@angular/platform-browser
'
;
import
{
BrowserAnimationsModule
}
from
'
@angular/platform-browser/animations
'
;
import
{
AppRoutingModule
}
from
'
./app-routing.module
'
;
import
{
ReactiveFormsModule
}
from
'
@angular/forms
'
;
import
{
CommandsComponent
}
from
'
./components/commands/commands.component
'
;
import
{
CommandsApi
}
from
'
./api/commands.api
'
;
import
{
MatSidenavModule
}
from
'
@angular/material/sidenav
'
;
@
NgModule
({
declarations
:
[
AppComponent
,
BookingsComponent
,
YearComponent
,
MessagesComponent
,
UserComponent
,
CallbackComponent
,
NavComponent
,
ErrorDialogComponent
,
NewBookingDialogComponent
,
CleanersComponent
,
NewCleanerDialogComponent
,
CommandsComponent
,
ErrorDialogComponent
],
imports
:
[
GoogleApiModule
.
forRoot
({
provide
:
NG_GAPI_CONFIG
,
useValue
:
gapiClientConfig
}),
AngularFireModule
.
initializeApp
(
FIREBASE
),
BrowserModule
,
AppRoutingModule
,
BrowserAnimationsModule
,
...
...
@@ -91,21 +66,17 @@ import { gapiClientConfig, WorkerService } from './services/worker.service';
MatSlideToggleModule
,
MatGridListModule
,
MatCardModule
,
MatMenuModule
,
NgxMaterialTimepickerModule
.
setLocale
(
'
fr-FR
'
),
MatMenuModule
],
providers
:
[
// services
LoadingService
,
UserService
,
WorkerService
,
// api
BookingsApi
,
UsersApi
,
CommandsApi
,
// interceptors
InterceptorProviders
,
],
bootstrap
:
[
AppComponent
],
entryComponents
:
[
ErrorDialogComponent
,
NewBookingDialogComponent
,
NewCleanerDialogComponent
],
entryComponents
:
[
ErrorDialogComponent
],
})
export
class
AppModule
{
}
ngx/src/app/components/bookings/bookings.component.html
deleted
100644 → 0
View file @
8ead6ae7
This diff is collapsed.
Click to expand it.
ngx/src/app/components/bookings/bookings.component.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable @typescript-eslint/member-ordering */
/* eslint-disable no-shadow */
/* eslint-disable eqeqeq */
/* eslint-disable @typescript-eslint/naming-convention */
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
*
as
moment
from
'
moment
'
;
import
{
Observable
,
of
}
from
'
rxjs
'
;
import
{
map
,
mergeMap
,
tap
}
from
'
rxjs/operators
'
;
import
{
AutoSendApi
}
from
'
src/app/api/autosend.api
'
;
import
{
BookingsApi
,
IPlatform
,
IState
}
from
'
src/app/api/bookings.api
'
;
import
{
IReport
,
ReportsApi
}
from
'
src/app/api/reports.api
'
;
import
{
BookingCtrl
}
from
'
src/app/controls/booking.control
'
;
import
{
Cleaner
}
from
'
src/app/controls/cleaner.control
'
;
import
{
CleaningCtrl
}
from
'
src/app/controls/cleaning.control
'
;
import
{
NewBookingCtrl
}
from
'
src/app/controls/newbooking.control
'
;
import
{
DialogService
}
from
'
src/app/services/dialog.service
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
@
Component
({
selector
:
'
app-bookings
'
,
templateUrl
:
'
./bookings.component.html
'
,
styleUrls
:
[
'
./bookings.component.css
'
],
})
export
class
BookingsComponent
implements
OnInit
{
// table columns
DISPLAYED_COLUMNS
:
string
[]
=
[
'
title
'
,
'
nights
'
,
'
checkinout
'
,
'
platform
'
,
'
autosend
'
,
'
cleaner
'
];
// Platforms
IPlatform
=
IPlatform
;
platformValues
=
Object
.
values
(
IPlatform
);
// States
IState
=
IState
;
stateValues
=
Object
.
values
(
IState
);
// variables
bookingsCtrls$
:
Observable
<
BookingCtrl
[]
>
=
of
([]);
monthly$
?:
Observable
<
IReport
>
;
// month
month
:
string
;
// Cleaners
cleaners
:
Cleaner
[]
=
[];
get
isToday
()
{
return
this
.
month
===
moment
().
format
(
'
YYYY-MM
'
);
}
constructor
(
public
bookingsApi
:
BookingsApi
,
public
autoSendApi
:
AutoSendApi
,
public
loadingService
:
LoadingService
,
public
userService
:
UserService
,
public
reportsApi
:
ReportsApi
,
public
dialogService
:
DialogService
,
)
{
const
userCtrl
=
this
.
userService
.
userCtrl
;
if
(
userCtrl
)
{
this
.
cleaners
=
userCtrl
.
api
().
cleaners
;
}
else
{
// TODO
}
this
.
month
=
moment
().
format
(
'
YYYY-MM
'
);
}
ngOnInit
()
{
this
.
bookingsCtrls$
=
this
.
bookingsApi
.
readBookings$
(
this
.
month
).
pipe
(
map
((
docs
)
=>
docs
.
map
((
doc
)
=>
new
BookingCtrl
(
doc
))),
);
// this.userService.read$().pipe(
// map(userCtrl => {
// this.cleaners = userCtrl.api().cleaners;
// })
// ).subscribe()
this
.
monthly$
=
this
.
reportsApi
.
readReport$
(
this
.
month
)
}
onRefresh
()
{
this
.
ngOnInit
();
}
onSync
()
{
this
.
monthly$
=
this
.
reportsApi
.
refreshReport$
(
this
.
month
);
this
.
bookingsCtrls$
=
this
.
bookingsApi
.
refreshBookings$
(
this
.
month
).
pipe
(
map
(
ibookings
=>
ibookings
.
map
(
ibooking
=>
new
BookingCtrl
(
ibooking
)))
);
}
onChange
(
control
:
BookingCtrl
)
{
if
(
control
.
cleaningCtrl
)
{
control
.
cleaningCtrl
=
undefined
;
}
else
if
(
this
.
cleaners
.
length
)
{
control
.
cleaningCtrl
=
new
CleaningCtrl
({
cleanerEmail
:
this
.
cleaners
[
0
].
email
,
hours
:
3
});
}
control
.
markAsDirty
();
}
onToday
()
{
this
.
month
=
moment
().
format
(
'
YYYY-MM
'
);
this
.
ngOnInit
();
}
onNext
()
{
this
.
month
=
moment
(
this
.
month
).
add
(
1
,
'
months
'
).
format
(
'
YYYY-MM
'
);
this
.
ngOnInit
();
}
onPrevious
()
{
this
.
month
=
moment
(
this
.
month
).
subtract
(
1
,
'
months
'
).
format
(
'
YYYY-MM
'
);
this
.
ngOnInit
();
}
onSend
()
{
this
.
bookingsCtrls$
=
this
.
autoSendApi
.
autoSendMyBookings$
(
this
.
month
).
pipe
(
map
((
docs
)
=>
docs
.
map
((
doc
)
=>
new
BookingCtrl
(
doc
))),
tap
(()
=>
this
.
onRefresh
())
);
}
onNew
()
{
const
newBookingCtrl
:
NewBookingCtrl
=
new
NewBookingCtrl
({
range
:
{
start
:
moment
(
this
.
month
).
format
(),
end
:
moment
(
this
.
month
).
add
(
3
,
'
days
'
).
format
(),
},
guest
:
{
email
:
'
john@yahoo.com
'
,
given
:
'
john
'
,
},
amount
:
200
,
platform
:
IPlatform
.
AIRBNB
});
this
.
dialogService
.
openNewBookingDialog$
(
newBookingCtrl
).
pipe
(
mergeMap
(
control
=>
this
.
bookingsApi
.
createBooking$
(
control
.
api
())),
map
(
ibooking
=>
new
BookingCtrl
(
ibooking
))
)
.
subscribe
(()
=>
this
.
onRefresh
())
}
onSubmit
(
control
:
BookingCtrl
)
{
this
.
bookingsApi
.
updateBooking$
(
control
.
api
()).
pipe
(
// take(1),
tap
(()
=>
control
.
markAsPristine
())
).
subscribe
(()
=>
this
.
onRefresh
());
}
onDelete
(
control
:
BookingCtrl
)
{
if
(
control
.
id
)
{
this
.
bookingsApi
.
deleteBooking$
(
control
.
id
).
subscribe
(()
=>
this
.
onRefresh
());
}
else
{
// TODO
}
}
}
ngx/src/app/components/callback/callback.component.css
deleted
100644 → 0
View file @
8ead6ae7
ngx/src/app/components/callback/callback.component.html
deleted
100644 → 0
View file @
8ead6ae7
<p>
authenticated!
</p>
ngx/src/app/components/callback/callback.component.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
@
Component
({
selector
:
'
app-callback
'
,
templateUrl
:
'
./callback.component.html
'
,
styleUrls
:
[
'
./callback.component.css
'
],
})
export
class
CallbackComponent
implements
OnInit
{
constructor
(
private
userService
:
UserService
)
{
}
ngOnInit
()
{
this
.
userService
.
onRegisterSuccess
();
}
}
ngx/src/app/components/cleaners/cleaners.component.css
deleted
100644 → 0
View file @
8ead6ae7
mat-form-field
{
width
:
50%
;
}
.grid-container
{
margin
:
20px
;
}
.dashboard-card
{
position
:
absolute
;
top
:
15px
;
left
:
15px
;
right
:
15px
;
bottom
:
15px
;
}
.more-button
{
position
:
absolute
;
top
:
5px
;
right
:
10px
;
}
.dashboard-card-content
{
text-align
:
center
;
}
img
.resize-gdrive
{
max-width
:
5%
;
max-height
:
3%
;
}
img
.resize-gdoc
{
max-width
:
8%
;
max-height
:
6%
;
}
ngx/src/app/components/cleaners/cleaners.component.html
deleted
100644 → 0
View file @
8ead6ae7
<form
*ngIf=
"userService.userCtrl$ | async as userCtrl"
[formGroup]=
"userCtrl"
fxLayout=
"column"
fxLayoutAlign=
"space-around"
class=
"grid-container"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"space-between center"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"start start"
>
<button
mat-icon-button
(click)=
"onRefresh()"
[disabled]=
"loadingService.isLoading$ | async"
>
<mat-icon>
refresh
</mat-icon>
</button>
<button
mat-icon-button
(click)=
"onSubmit(userCtrl)"
[disabled]=
"userCtrl.pristine"
>
<mat-icon>
save
</mat-icon>
</button>
</div>
<button
mat-icon-button
(click)=
"onNew()"
>
<mat-icon>
add
</mat-icon>
</button>
</div>
<mat-grid-list
cols=
"2"
rowHeight=
"350px"
>
<mat-grid-tile
*ngFor=
"let cleanerCtrl of cleanersCtrls(userCtrl)"
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header
fxLayout=
"row"
fxLayoutAlign=
"space-between center"
>
<mat-card-title>
{{ cleanerCtrl.nameFC.value }}
</mat-card-title>
<button
mat-icon-button
(click)=
"onDelete(cleanerCtrl)"
fxFlexAlign=
"end"
>
<mat-icon>
delete
</mat-icon>
</button>
</mat-card-header>
<mat-card-content
fxLayout=
"column"
fxLayoutAlign=
"space-around start"
class=
"dashboard-card-content"
>
<mat-form-field
fxFlexFill
>
<mat-label>
Name
</mat-label>
<input
input
matInput
[formControl]=
"cleanerCtrl.nameFC"
/>
</mat-form-field>
<mat-form-field
fxFlexFill
>
<mat-label>
Email
</mat-label>
<input
input
matInput
[formControl]=
"cleanerCtrl.emailFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Rate
</mat-label>
<input
input
matInput
[formControl]=
"cleanerCtrl.rateFC"
/>
<span
matSuffix
>
/hour
</span>
</mat-form-field>
<mat-slide-toggle
[formControl]=
"cleanerCtrl.defaultFC"
>
default
</mat-slide-toggle>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
</form>
\ No newline at end of file
ngx/src/app/components/cleaners/cleaners.component.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
MatDialog
}
from
'
@angular/material/dialog
'
;
// import { UsersApi } from 'src/app/api/users.api';
import
{
CleanerCtrl
}
from
'
src/app/controls/cleaner.control
'
;
import
{
UserCtrl
}
from
'
src/app/controls/user.control
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
import
{
NewCleanerDialogComponent
}
from
'
../new-cleaner-dialog/new-cleaner.component
'
;
@
Component
({
selector
:
'
app-cleaners
'
,
templateUrl
:
'
./cleaners.component.html
'
,
styleUrls
:
[
'
./cleaners.component.css
'
],
})
export
class
CleanersComponent
implements
OnInit
{
constructor
(
// private usersApi: UsersApi,
public
loadingService
:
LoadingService
,
public
userService
:
UserService
,
public
dialog
:
MatDialog
,
)
{
}
ngOnInit
()
{
this
.
userService
.
read$
().
subscribe
();
}
onRefresh
()
{
this
.
ngOnInit
();
}
cleanersCtrls
(
userCtrl
:
UserCtrl
)
{
return
userCtrl
.
cleanersFA
.
controls
as
CleanerCtrl
[];
}
onSubmit
(
userCtrl
:
UserCtrl
)
{
this
.
userService
.
update$
(
userCtrl
).
subscribe
(()
=>
this
.
onRefresh
());
}
onDelete
(
control
:
CleanerCtrl
)
{
const
userCtrl
=
this
.
userService
.
userCtrl
;
if
(
userCtrl
)
{
const
index
=
userCtrl
.
cleanersFA
.
controls
.
indexOf
(
control
);
if
(
index
>
-
1
)
{
userCtrl
.
cleanersFA
.
controls
.
splice
(
index
,
1
);
}
this
.
onSubmit
(
userCtrl
);
}
else
{
// TODO
}
}
onNew
()
{
const
dialogRef
=
this
.
dialog
.
open
(
NewCleanerDialogComponent
,
{
width
:
'
400px
'
,
data
:
CleanerCtrl
.
newCleanerCtrl
(),
});
dialogRef
.
afterClosed
().
subscribe
((
control
)
=>
{
const
userCtrl
=
this
.
userService
.
userCtrl
;
if
(
userCtrl
)
{
userCtrl
.
cleanersFA
.
push
(
control
);
this
.
onSubmit
(
userCtrl
);
}
else
{
// TODO
}
});
}
}
ngx/src/app/components/
bookings/booking
s.component.css
→
ngx/src/app/components/
commands/command
s.component.css
View file @
51362d9c
File moved
ngx/src/app/components/commands/commands.component.html
0 → 100644
View file @
51362d9c
<h1
mat-dialog-title
>
Status
</h1>
<mat-form-field
*ngIf=
"commandsCtrls$ | async as commands"
>
<mat-label>
Command
</mat-label>
<mat-select
[formControl]=
"selectedCtrl!.nameFC"
[value]=
"selectedCtrl!.nameFC.value"
>
<mat-option
*ngFor=
"let command of commands"
[value]=
"command"
>
{{ command }}
</mat-option>
</mat-select>
</mat-form-field>
\ No newline at end of file
ngx/src/app/components/commands/commands.component.ts
0 → 100644
View file @
51362d9c
/* eslint-disable @typescript-eslint/member-ordering */
/* eslint-disable no-shadow */
/* eslint-disable eqeqeq */
/* eslint-disable @typescript-eslint/naming-convention */
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
Observable
,
of
}
from
'
rxjs
'
;
import
{
map
,
mergeMap
,
tap
}
from
'
rxjs/operators
'
;
import
{
CommandsApi
}
from
'
src/app/api/commands.api
'
;
import
{
CommandCtrl
}
from
'
src/app/controls/command.control
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
@
Component
({
selector
:
'
app-commands
'
,
templateUrl
:
'
./commands.component.html
'
,
styleUrls
:
[
'
./commands.component.css
'
],
})
export
class
CommandsComponent
{
commandsCtrls$
:
Observable
<
CommandCtrl
[]
>
selectedCtrl
?:
CommandCtrl
constructor
(
public
commandsApi
:
CommandsApi
,
public
autoSendApi
:
CommandsApi
,
public
loadingService
:
LoadingService
,
)
{
this
.
commandsCtrls$
=
this
.
commandsApi
.
readCommands$
().
pipe
(
map
((
docs
)
=>
docs
.
map
((
doc
)
=>
new
CommandCtrl
(
doc
))),
);
}
onSubmit
(
control
:
CommandCtrl
)
{
this
.
commandsApi
.
runCommand$
(
control
.
api
()).
pipe
(
// take(1),
tap
(()
=>
control
.
markAsPristine
())
).
subscribe
();
}
}
ngx/src/app/components/messages/messages.component.css
deleted
100644 → 0
View file @
8ead6ae7
mat-form-field
{
width
:
50%
;
}
.grid-container
{
margin
:
20px
;
}
.dashboard-card
{
position
:
absolute
;
top
:
15px
;
left
:
15px
;
right
:
15px
;
bottom
:
15px
;
}
.more-button
{
position
:
absolute
;
top
:
5px
;
right
:
10px
;
}
.dashboard-card-content
{
text-align
:
center
;
}
img
.resize-gdrive
{
max-width
:
5%
;
max-height
:
3%
;
}
img
.resize-gdoc
{
max-width
:
8%
;
max-height
:
6%
;
}
ngx/src/app/components/messages/messages.component.html
deleted
100644 → 0
View file @
8ead6ae7
<form
*ngIf=
"userService.userCtrl$ | async as userCtrl"
[formGroup]=
"userCtrl"
fxLayout=
"column"
fxLayoutAlign=
"space-around"
class=
"grid-container"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"space-between center"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"start start"
>
<button
mat-icon-button
(click)=
"onRefresh()"
[disabled]=
"loadingService.isLoading$ | async"
>
<mat-icon>
refresh
</mat-icon>
</button>
<button
mat-icon-button
(click)=
"onSubmit(userCtrl)"
[disabled]=
"userCtrl.pristine"
>
<mat-icon>
save
</mat-icon>
</button>
</div>
<button
mat-raised-button
color=
"primary"
(click)=
"userService.register()"
*ngIf=
"(userService.isRegistered$ | async) === false"
>
REGISTER
</button>
<button
mat-raised-button
color=
"primary"
(click)=
"userService.unregister()"
*ngIf=
"userService.isRegistered$ | async"
>
UNREGISTER
</button>
<!--
<button mat-raised-button color="primary" (click)="userService.register()">
REGISTER
</button>
<button mat-raised-button color="primary" (click)="userService.unregister()">
UNREGISTER
</button> -->
</div>
<mat-grid-list
cols=
"2"
rowHeight=
"350px"
>
<mat-grid-tile
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header
fxLayout=
"row"
fxLayoutAlign=
"space-between center"
>
<mat-card-title>
Autosend
</mat-card-title>
<mat-slide-toggle
[formControl]=
"userCtrl.autoSendFC"
[disabled]=
"!userCtrl.isRegistered"
></mat-slide-toggle>
</mat-card-header>
<mat-card-content
fxLayout=
"column"
fxLayoutAlign=
"start start"
class=
"dashboard-card-content"
>
<mat-form-field>
<mat-label>
Email subject prefix
</mat-label>
<span
matPrefix
>
[
</span>
<input
input
matInput
[formControl]=
"userCtrl.subjectPrefixFC"
/>
<span
matSuffix
>
]
</span>
</mat-form-field>
<mat-form-field
fxFlexFill
>
<mat-label>
Address
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.addressFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Name
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.nameFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Tel
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.telFC"
/>
</mat-form-field>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<div
*ngIf=
"userCtrl.autoSendFC.value"
>
<mat-grid-tile
*ngFor=
"let messageCtrl of messagesCtrls(userCtrl)"
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
{{ messageCtrl.subject }}
</mat-card-title>
</mat-card-header>
<mat-card-content
class=
"dashboard-card-content"
>
<mat-form-field
fxFlexFill
>
<mat-label>
Body
</mat-label>
<textarea
matInput
[formControl]=
"messageCtrl.bodyFC"
cdkTextareaAutosize
></textarea>
</mat-form-field>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</div>
</mat-grid-list>
</form>
\ No newline at end of file
ngx/src/app/components/messages/messages.component.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
UserCtrl
}
from
'
src/app/controls/user.control
'
;
import
{
MessageCtrl
}
from
'
src/app/controls/message.control
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
@
Component
({
selector
:
'
app-messages
'
,
templateUrl
:
'
./messages.component.html
'
,
styleUrls
:
[
'
./messages.component.css
'
],
})
export
class
MessagesComponent
implements
OnInit
{
constructor
(
public
loadingService
:
LoadingService
,
public
userService
:
UserService
)
{
}
ngOnInit
()
{
this
.
userService
.
read$
().
subscribe
();
}
onRefresh
()
{
this
.
ngOnInit
();
}
messagesCtrls
(
userCtrl
:
UserCtrl
)
{
return
userCtrl
.
messagesFA
.
controls
as
MessageCtrl
[];
}
onSubmit
(
userCtrl
:
UserCtrl
)
{
this
.
userService
.
update$
(
userCtrl
).
subscribe
(()
=>
this
.
onRefresh
());
}
}
ngx/src/app/components/nav/nav.component.html
View file @
51362d9c
...
...
@@ -2,11 +2,8 @@
<mat-sidenav
#drawer
class=
"sidenav"
fixedInViewport
[attr.role]=
"(isHandset$ | async) ? 'dialog' : 'navigation'"
[mode]=
"(isHandset$ | async) ? 'over' : 'side'"
[opened]=
"(isHandset$ | async) === false"
>
<mat-nav-list>
<a
mat-list-item
routerLink=
"/bookings"
routerLinkActive=
"active"
>
Month
</a>
<a
mat-list-item
routerLink=
"/year"
routerLinkActive=
"active"
>
Year
</a>
<a
mat-list-item
routerLink=
"/messages"
routerLinkActive=
"active"
>
Autosend
</a>
<a
mat-list-item
routerLink=
"/cleaners"
routerLinkActive=
"active"
>
Cleaners
</a>
<a
mat-list-item
routerLink=
"/user"
routerLinkActive=
"active"
>
Calendars
</a>
<a
mat-list-item
routerLink=
"/commands"
routerLinkActive=
"active"
>
Commands
</a>
<a
mat-list-item
routerLink=
"/logs"
routerLinkActive=
"active"
>
Logs
</a>
</mat-nav-list>
</mat-sidenav>
...
...
@@ -18,31 +15,21 @@
<button
mat-icon-button
(click)=
"drawer.toggle()"
>
<mat-icon>
menu
</mat-icon>
</button>
<h1>
LSD
</h1>
<h1>
OAI SoftModem
</h1>
</ng-template>
<ng-template
#loading
>
<mat-progress-spinner
mode=
"indeterminate"
diameter=
"40"
>
</mat-progress-spinner>
<mat-progress-spinner
mode=
"indeterminate"
diameter=
"40"
>
</mat-progress-spinner>
</ng-template>
<div
fxLayout=
"row"
fxLayoutAlign=
"start center"
>
<ng-container
*ngIf=
"loadingService.isLoading$ | async; then loading; else not_loading"
>
</ng-container>
</div>
<ng-template
#notAuthenticated
>
<button
mat-raised-button
color=
"primary"
*ngIf=
"(userService.isAuthenticated$ | async) === false"
(click)=
"userService.login()"
>
login
</button>
</ng-template>
<ng-template
#authenticated
>
<ng-container
fxLayout=
"row"
>
<a
id=
"email"
>
{{ userService.email }}
</a>
<button
mat-raised-button
color=
"warn"
href=
"#"
(click)=
"userService.logout()"
>
logout
</button>
</ng-template>
<ng-container
*ngIf=
"userService.isAuthenticated$ | async; then authenticated; else notAuthenticated"
fxLayout=
"row"
>
</ng-container>
</mat-toolbar-row>
...
...
ngx/src/app/components/nav/nav.component.ts
View file @
51362d9c
import
{
Component
}
from
'
@angular/core
'
;
import
{
BreakpointObserver
,
Breakpoints
}
from
'
@angular/cdk/layout
'
;
import
{
Component
}
from
'
@angular/core
'
;
import
{
Observable
}
from
'
rxjs
'
;
import
{
map
,
shareReplay
}
from
'
rxjs/operators
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
@
Component
({
...
...
@@ -17,5 +16,5 @@ export class NavComponent {
);
constructor
(
public
loadingService
:
LoadingService
,
p
ublic
userService
:
UserService
,
p
rivate
breakpointObserver
:
BreakpointObserver
)
{
}
public
loadingService
:
LoadingService
,
private
breakpointObserver
:
BreakpointObserver
)
{
}
}
ngx/src/app/components/new-booking-dialog/new-booking.component.html
deleted
100644 → 0
View file @
8ead6ae7
<h1
mat-dialog-title
>
New Booking
</h1>
<div
mat-dialog-content
>
<mat-form-field>
<mat-label>
Given name
</mat-label>
<input
input
matInput
[formControl]=
"bookingCtrl.guestCtrl.givenFC"
/>
</mat-form-field>
<mat-form-field
fxFlexFill
>
<mat-label>
Nights
</mat-label>
<mat-date-range-input
[rangePicker]=
"picker"
>
<input
matStartDate
[formControl]=
"bookingCtrl.rangeCtrl.startDayFC"
/>
<input
matEndDate
[formControl]=
"bookingCtrl.rangeCtrl.endDayFC"
/>
</mat-date-range-input>
<mat-datepicker-toggle
matSuffix
[for]=
"picker"
></mat-datepicker-toggle>
<mat-date-range-picker
#picker
></mat-date-range-picker>
</mat-form-field>
<mat-form-field>
<mat-label>
Platform
</mat-label>
<mat-select
[formControl]=
"bookingCtrl.platformFC"
[value]=
"bookingCtrl.platformFC.value"
>
<mat-option
*ngFor=
"let platform of platformValues"
[value]=
"platform"
>
{{ platform }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>
Email
</mat-label>
<input
input
matInput
[formControl]=
"bookingCtrl.guestCtrl.emailFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Amount
</mat-label>
<input
input
matInput
[formControl]=
"bookingCtrl.amountFC"
/>
</mat-form-field>
</div>
<div
mat-dialog-actions
>
<button
mat-button
(click)=
"onNoClick()"
>
Cancel
</button>
<button
mat-button
[mat-dialog-close]=
"bookingCtrl"
cdkFocusInitial
>
Ok
</button>
</div>
\ No newline at end of file
ngx/src/app/components/new-booking-dialog/new-booking.component.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable @typescript-eslint/naming-convention */
import
{
Component
,
Inject
}
from
'
@angular/core
'
;
import
{
MatDialogRef
,
MAT_DIALOG_DATA
}
from
'
@angular/material/dialog
'
;
import
{
IPlatform
,
IState
}
from
'
src/app/api/bookings.api
'
;
import
{
Cleaner
}
from
'
src/app/controls/cleaner.control
'
;
import
{
NewBookingCtrl
}
from
'
src/app/controls/newbooking.control
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
@
Component
({
selector
:
'
app-new-booking
'
,
templateUrl
:
'
./new-booking.component.html
'
,
})
export
class
NewBookingDialogComponent
{
// Platforms
IPlatform
=
IPlatform
;
platformValues
=
Object
.
values
(
IPlatform
);
// States
IState
=
IState
;
stateValues
=
Object
.
values
(
IState
);
// Cleaners
cleaners
?:
Cleaner
[];
constructor
(
public
dialogRef
:
MatDialogRef
<
NewBookingDialogComponent
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
bookingCtrl
:
NewBookingCtrl
,
public
userService
:
UserService
,
)
{
const
userCtrl
=
this
.
userService
.
userCtrl
;
if
(
userCtrl
)
{
this
.
cleaners
=
userCtrl
.
api
().
cleaners
;
}
else
{
// TODO
}
}
onNoClick
()
{
this
.
dialogRef
.
close
();
}
}
ngx/src/app/components/new-cleaner-dialog/new-cleaner.component.html
deleted
100644 → 0
View file @
8ead6ae7
<h1
mat-dialog-title
>
New Cleaner
</h1>
<div
mat-dialog-content
>
<mat-form-field>
<mat-label>
Name
</mat-label>
<input
input
matInput
[formControl]=
"cleanerCtrl.nameFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Email
</mat-label>
<input
input
matInput
[formControl]=
"cleanerCtrl.emailFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Rate
</mat-label>
<input
input
matInput
[formControl]=
"cleanerCtrl.rateFC"
/>
</mat-form-field>
</div>
<div
mat-dialog-actions
>
<button
mat-button
(click)=
"onNoClick()"
>
Cancel
</button>
<button
mat-button
[mat-dialog-close]=
"cleanerCtrl"
cdkFocusInitial
>
Ok
</button>
</div>
ngx/src/app/components/new-cleaner-dialog/new-cleaner.component.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
Component
,
Inject
}
from
'
@angular/core
'
;
import
{
MatDialogRef
,
MAT_DIALOG_DATA
}
from
'
@angular/material/dialog
'
;
import
{
CleanerCtrl
}
from
'
../../controls/cleaner.control
'
;
@
Component
({
selector
:
'
app-new-cleaner
'
,
templateUrl
:
'
./new-cleaner.component.html
'
,
})
export
class
NewCleanerDialogComponent
{
constructor
(
public
dialogRef
:
MatDialogRef
<
NewCleanerDialogComponent
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
cleanerCtrl
:
CleanerCtrl
)
{
}
onNoClick
()
{
this
.
dialogRef
.
close
();
}
}
ngx/src/app/components/user/user.component.css
deleted
100644 → 0
View file @
8ead6ae7
mat-form-field
{
width
:
50%
;
}
.grid-container
{
margin
:
20px
;
}
.dashboard-card
{
position
:
absolute
;
top
:
15px
;
left
:
15px
;
right
:
15px
;
bottom
:
15px
;
}
.more-button
{
position
:
absolute
;
top
:
5px
;
right
:
10px
;
}
.dashboard-card-content
{
text-align
:
center
;
}
img
.resize-gdrive
{
max-width
:
5%
;
max-height
:
3%
;
}
img
.resize-gdoc
{
max-width
:
8%
;
max-height
:
6%
;
}
ngx/src/app/components/user/user.component.html
deleted
100644 → 0
View file @
8ead6ae7
<form
*ngIf=
"userService.userCtrl$ | async as userCtrl"
[formGroup]=
"userCtrl"
fxLayout=
"column"
fxLayoutAlign=
"space-around"
class=
"grid-container"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"space-between center"
>
<div
fxLayout=
"row"
>
<button
mat-icon-button
(click)=
"onRefresh()"
[disabled]=
"loadingService.isLoading$ | async"
>
<mat-icon>
refresh
</mat-icon>
</button>
<button
mat-icon-button
(click)=
"onSubmit(userCtrl)"
[disabled]=
"userCtrl.pristine"
>
<mat-icon>
save
</mat-icon>
</button>
</div>
<button
mat-icon-button
(click)=
"onSync()"
[disabled]=
"loadingService.isLoading$ | async"
>
<mat-icon>
sync
</mat-icon>
</button>
</div>
<mat-grid-list
cols=
"2"
rowHeight=
"150px"
>
<mat-grid-tile
[colspan]=
"2"
[rowspan]=
"2"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Settings
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayout=
"column"
fxLayoutAlign=
"start start"
class=
"dashboard-card-content"
>
<mat-form-field>
<mat-label>
Checkin Hour
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.defaultCheckInHourFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Checkout Hour
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.defaultCheckOutHourFC"
/>
</mat-form-field>
<mat-form-field>
<mat-label>
Cleaning Time
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.defaultCleaningHoursFC"
/>
</mat-form-field>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"2"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Nights
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayout=
"column"
class=
"dashboard-card-content"
>
<div
fxLayout=
"row"
fxFill
>
<mat-form-field>
<mat-label>
Calendar ID
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.busyCalCtrl.idFC"
/>
</mat-form-field>
<button
mat-icon-button
[cdkCopyToClipboard]=
"ical(userCtrl.busyCalCtrl.idFC.value)"
>
<mat-icon>
content_copy
</mat-icon>
</button>
<p>
{{ userCtrl.busyCalCtrl.summaryFC.value }}
</p>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"2"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Real
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayout=
"column"
class=
"dashboard-card-content"
>
<div
fxLayout=
"row"
fxFill
>
<mat-form-field>
<mat-label>
Calendar ID
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.reelCalCtrl.idFC"
/>
</mat-form-field>
<button
mat-icon-button
[cdkCopyToClipboard]=
"ical(userCtrl.reelCalCtrl.idFC.value)"
>
<mat-icon>
content_copy
</mat-icon>
</button>
<p>
{{ userCtrl.reelCalCtrl.summaryFC.value }}
</p>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"2"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Cleanings
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayout=
"column"
class=
"dashboard-card-content"
>
<div
fxLayout=
"row"
fxFill
>
<mat-form-field>
<mat-label>
Calendar ID
</mat-label>
<input
input
matInput
[formControl]=
"userCtrl.cleaningCalCtrl.idFC"
/>
</mat-form-field>
<button
mat-icon-button
[cdkCopyToClipboard]=
"ical(userCtrl.cleaningCalCtrl.idFC.value)"
>
<mat-icon>
content_copy
</mat-icon>
</button>
<p>
{{ userCtrl.cleaningCalCtrl.summaryFC.value }}
</p>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
</form>
\ No newline at end of file
ngx/src/app/components/user/user.component.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable @typescript-eslint/member-ordering */
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
UserCtrl
}
from
'
src/app/controls/user.control
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
import
{
UserService
}
from
'
./../../services/user.service
'
;
@
Component
({
selector
:
'
app-user
'
,
templateUrl
:
'
./user.component.html
'
,
styleUrls
:
[
'
./user.component.css
'
],
})
export
class
UserComponent
implements
OnInit
{
onRefresh
=
this
.
ngOnInit
;
constructor
(
public
userService
:
UserService
,
public
loadingService
:
LoadingService
)
{
}
ngOnInit
()
{
this
.
userService
.
read$
().
subscribe
();
}
onSync
()
{
this
.
userService
.
refresh$
().
subscribe
();
}
onSubmit
(
userCtrl
:
UserCtrl
)
{
this
.
userService
.
update$
(
userCtrl
).
subscribe
(()
=>
this
.
onRefresh
());
}
ical
(
id
:
string
)
{
return
'
https://calendar.google.com/calendar/ical/
'
+
encodeURIComponent
(
id
)
+
'
/public/basic.ics
'
;
}
}
ngx/src/app/components/year/year.component.css
deleted
100644 → 0
View file @
8ead6ae7
mat-form-field
{
width
:
50%
;
}
.status
{
color
:
green
;
font-weight
:
800
;
}
.ng-invalid
.status
{
color
:
red
;
}
.grid-container
{
margin
:
20px
;
}
.dashboard-card
{
position
:
absolute
;
top
:
15px
;
left
:
15px
;
right
:
15px
;
bottom
:
15px
;
}
.more-button
{
position
:
absolute
;
top
:
5px
;
right
:
10px
;
}
.dashboard-card-content
{
text-align
:
center
;
}
ngx/src/app/components/year/year.component.html
deleted
100644 → 0
View file @
8ead6ae7
<div
class=
"grid-container"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"space-between"
>
<div
fxLayout=
"row"
fxLayoutAlign=
"start end"
>
<button
mat-icon-button
(click)=
"onRefresh()"
[disabled]=
"loadingService.isLoading$ | async"
>
<mat-icon>
refresh
</mat-icon>
</button>
</div>
<div
fxLayout=
"row"
fxLayoutAlign=
"space-around end"
>
<button
mat-icon-button
(click)=
"onPrevious()"
>
<mat-icon>
skip_previous
</mat-icon>
</button>
<p>
{{ year }}
</p>
<button
mat-icon-button
(click)=
"onNext()"
>
<mat-icon>
skip_next
</mat-icon>
</button>
</div>
<div
fxLayout=
"row"
fxLayoutAlign=
"end end"
>
<button
mat-icon-button
(click)=
"onSync()"
[disabled]=
"loadingService.isLoading$ | async"
>
<mat-icon>
sync
</mat-icon>
</button>
</div>
</div>
<mat-grid-list
*ngIf=
"yearly$ | async as yearly"
cols=
"5"
rowHeight=
"150px"
>
<mat-grid-tile
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
{{ yearly.nights }} nights
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayoutAlign=
"center center"
fxLAyoutAlign=
"center center"
class=
"dashboard-card-content"
>
<h1>
{{ yearly.occupation }}%
</h1>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Brut
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayoutAlign=
"center center"
class=
"dashboard-card-content"
>
<h1>
{{ yearly.brut }}€
</h1>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Cleanings
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayoutAlign=
"center center"
fxLAyoutAlign=
"center center"
class=
"dashboard-card-content"
>
<h1>
{{ yearly.cleanings }}€
</h1>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Net
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayoutAlign=
"center center"
fxLAyoutAlign=
"center center"
class=
"dashboard-card-content"
>
<h1>
{{ yearly.net }}€
</h1>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"1"
[rowspan]=
"1"
>
<mat-card
class=
"dashboard-card"
>
<mat-card-header>
<mat-card-title>
Night Rate
</mat-card-title>
</mat-card-header>
<mat-card-content
fxLayoutAlign=
"center center"
fxLAyoutAlign=
"center center"
class=
"dashboard-card-content"
>
<h1>
{{ yearly.nightRate }}€
</h1>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile
[colspan]=
"5"
[rowspan]=
"15"
>
<div
fxLayout=
"column"
fxLayoutAlign=
"start"
fxFlexFill
>
<div
*ngIf=
"bookingsCtrls$ | async as bookingsCtrls"
>
<!-- <mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator> -->
<mat-table
mat-table
[dataSource]=
"bookingsCtrls"
multiTemplateDataRows
class=
"mat-elevation-z8"
>
<ng-container
matColumnDef=
"dates"
>
<mat-header-cell
*matHeaderCellDef
>
<h2>
Dates
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{dates(bookingCtrl)}}
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"guest"
>
<mat-header-cell
*matHeaderCellDef
>
<h2>
Guest
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{bookingCtrl.guestCtrl.givenFC.value}}
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"nights"
>
<mat-header-cell
*matHeaderCellDef
>
<h2>
Nights
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{nights(bookingCtrl)}}
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"platform"
>
<mat-header-cell
*matHeaderCellDef
>
<h2>
Platform
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{ bookingCtrl.platformFC.value }}
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"rate"
>
<mat-header-cell
*matHeaderCellDef
>
<h2>
Rate
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{ rate(bookingCtrl)}}
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"brut"
>
<mat-header-cell
*matHeaderCellDef
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
<h2>
Brut
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
<mat-form-field>
<mat-label>
Amount
</mat-label>
<input
input
matInput
[formControl]=
"bookingCtrl.amountFC"
/>
</mat-form-field>
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"cleanings"
>
<mat-header-cell
*matHeaderCellDef
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
<h2>
Cleanings
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{ cleaning(bookingCtrl) }}
</mat-cell>
</ng-container>
<ng-container
matColumnDef=
"net"
>
<mat-header-cell
*matHeaderCellDef
>
<h2>
Net
</h2>
</mat-header-cell>
<mat-cell
*matCellDef=
"let bookingCtrl"
fxLayout=
"column"
fxLayoutAlign=
"start start"
>
{{ brut(bookingCtrl) - cleaning(bookingCtrl) }}
</mat-cell>
</ng-container>
<mat-header-row
*matHeaderRowDef=
"DISPLAYED_COLUMNS"
></mat-header-row>
<mat-row
*matRowDef=
"let bookingCtrl; columns: DISPLAYED_COLUMNS"
(keydown.enter)=
"onSubmit(bookingCtrl)"
>
</mat-row>
</mat-table>
</div>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
\ No newline at end of file
ngx/src/app/components/year/year.component.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable @typescript-eslint/member-ordering */
/* eslint-disable no-shadow */
/* eslint-disable eqeqeq */
/* eslint-disable @typescript-eslint/naming-convention */
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
*
as
moment
from
'
moment
'
;
import
{
BehaviorSubject
,
Observable
,
of
}
from
'
rxjs
'
;
import
{
map
,
mergeMap
,
tap
}
from
'
rxjs/operators
'
;
import
{
AutoSendApi
}
from
'
src/app/api/autosend.api
'
;
import
{
BookingsApi
,
IPlatform
}
from
'
src/app/api/bookings.api
'
;
import
{
IReport
,
ReportsApi
}
from
'
src/app/api/reports.api
'
;
import
{
LoadingService
}
from
'
src/app/services/loading.service
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
import
{
BookingCtrl
}
from
'
../../controls/booking.control
'
;
@
Component
({
selector
:
'
app-year
'
,
templateUrl
:
'
./year.component.html
'
,
styleUrls
:
[
'
./year.component.css
'
],
})
export
class
YearComponent
implements
OnInit
{
DISPLAYED_COLUMNS
:
string
[]
=
[
'
dates
'
,
'
guest
'
,
'
nights
'
,
'
platform
'
,
'
rate
'
,
'
brut
'
,
'
cleanings
'
,
'
net
'
];
year
:
string
;
yearly$
?:
Observable
<
IReport
>
;
bookingsCtrls$
?:
Observable
<
BookingCtrl
[]
>
;
rates
=
new
Map
<
string
,
number
>
();
constructor
(
public
bookingsApi
:
BookingsApi
,
public
reportsApi
:
ReportsApi
,
public
autoSendApi
:
AutoSendApi
,
public
loadingService
:
LoadingService
,
public
userService
:
UserService
,
)
{
this
.
year
=
moment
().
format
(
'
YYYY
'
);
const
userCtrl
=
this
.
userService
.
userCtrl
;
if
(
userCtrl
)
{
userCtrl
.
api
().
cleaners
.
forEach
((
cleaner
)
=>
this
.
rates
.
set
(
cleaner
.
email
,
cleaner
.
rate
));
}
else
{
// TODO
}
}
onNext
()
{
this
.
year
=
moment
(
this
.
year
).
add
(
1
,
'
years
'
).
format
(
'
YYYY
'
);
this
.
ngOnInit
();
}
nights
(
control
:
BookingCtrl
)
{
return
moment
(
control
.
rangeCtrl
.
endDayFC
.
value
).
diff
(
moment
(
control
.
rangeCtrl
.
startDayFC
.
value
),
'
days
'
)
+
1
}
dates
(
control
:
BookingCtrl
)
{
return
moment
(
control
.
rangeCtrl
.
startDayFC
.
value
).
format
(
'
DD/MM
'
)
+
'
to
'
+
moment
(
control
.
rangeCtrl
.
endDayFC
.
value
).
format
(
'
DD/MM
'
)
}
rate
(
control
:
BookingCtrl
)
{
return
Math
.
round
(
this
.
brut
(
control
)
/
this
.
nights
(
control
))
}
brut
(
control
:
BookingCtrl
)
{
let
comission
=
0
if
(
control
.
platformFC
.
value
===
IPlatform
.
BOOKING
)
comission
=
0.2
return
(
1
-
comission
)
*
control
.
amountFC
.
value
;
}
cleaning
(
control
:
BookingCtrl
)
{
return
control
.
cleaningCtrl
?
this
.
rates
.
get
(
control
.
cleaningCtrl
.
cleanerEmailFC
.
value
)
!
*
control
.
cleaningCtrl
.
hours
:
0
}
onPrevious
()
{
this
.
year
=
moment
(
this
.
year
).
subtract
(
1
,
'
years
'
).
format
(
'
YYYY
'
);
this
.
ngOnInit
();
}
onRefresh
()
{
this
.
ngOnInit
();
}
onSync
()
{
this
.
yearly$
=
this
.
reportsApi
.
refreshReports$
(
this
.
year
).
pipe
(
map
(
this
.
processReports
)
)
this
.
bookingsCtrls$
=
this
.
yearly$
.
pipe
(
mergeMap
(
yearly
=>
this
.
bookingsApi
.
readBookingsList$
(
yearly
.
bookings
)),
map
(
ibookings
=>
ibookings
.
map
(
ibooking
=>
new
BookingCtrl
(
ibooking
)))
);
}
ngOnInit
()
{
this
.
yearly$
=
this
.
reportsApi
.
readReports$
(
this
.
year
).
pipe
(
map
(
this
.
processReports
)
)
this
.
bookingsCtrls$
=
this
.
yearly$
.
pipe
(
mergeMap
(
yearly
=>
this
.
bookingsApi
.
readBookingsList$
(
yearly
.
bookings
)),
map
(
ibookings
=>
ibookings
.
map
(
ibooking
=>
new
BookingCtrl
(
ibooking
)))
);
}
private
processReports
(
ireports
:
IReport
[])
{
let
yearly
:
IReport
=
{
brut
:
0
,
cleanings
:
0
,
month
:
this
.
year
,
//FIXME
nights
:
0
,
occupation
:
0
,
net
:
0
,
bookings
:
[]
};
ireports
.
forEach
((
ireport
)
=>
{
yearly
.
brut
=
yearly
.
brut
+
ireport
.
brut
;
yearly
.
cleanings
=
yearly
.
cleanings
+
ireport
.
cleanings
;
yearly
.
nights
=
yearly
.
nights
+
ireport
.
nights
;
yearly
.
bookings
=
yearly
.
bookings
.
concat
(
ireport
.
bookings
);
})
yearly
.
net
=
yearly
.
brut
-
yearly
.
cleanings
;
yearly
.
netRate
=
Math
.
round
(
yearly
.
net
/
yearly
.
nights
);
yearly
.
nightRate
=
Math
.
round
(
yearly
.
brut
/
yearly
.
nights
);
yearly
.
occupation
=
Math
.
round
(
100
*
yearly
.
nights
/
365
);
return
yearly
}
onSubmit
(
control
:
BookingCtrl
)
{
this
.
bookingsApi
.
updateBooking$
(
control
.
api
()).
pipe
(
// take(1),
tap
(()
=>
control
.
markAsPristine
())
).
subscribe
();
}
}
ngx/src/app/controls/booking.control.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable no-shadow */
import
{
FormControl
}
from
'
@angular/forms
'
;
import
{
IBooking
,
IState
}
from
'
../api/bookings.api
'
;
import
{
Cleaning
,
CleaningCtrl
}
from
'
./cleaning.control
'
;
import
{
NewBooking
,
NewBookingCtrl
}
from
'
./newbooking.control
'
;
const
enum
BookingFCN
{
state
=
'
state
'
,
cleaning
=
'
cleaning
'
,
}
export
class
Booking
extends
NewBooking
{
id
:
string
;
month
:
string
;
state
:
IState
;
cleaning
?:
Cleaning
;
constructor
(
iBooking
:
IBooking
)
{
super
(
iBooking
)
this
.
id
=
iBooking
.
id
;
this
.
month
=
iBooking
.
month
;
this
.
state
=
iBooking
.
state
;
if
(
iBooking
.
cleaning
)
{
this
.
cleaning
=
new
Cleaning
(
iBooking
.
cleaning
);
}
else
{
this
.
cleaning
=
undefined
;
}
}
}
export
class
BookingCtrl
extends
NewBookingCtrl
{
id
:
string
;
month
:
string
;
constructor
(
ibooking
:
IBooking
)
{
super
(
ibooking
);
const
booking
=
new
Booking
(
ibooking
);
this
.
id
=
booking
.
id
;
this
.
month
=
booking
.
month
;
if
(
booking
.
cleaning
)
{
this
.
addControl
(
BookingFCN
.
cleaning
,
new
CleaningCtrl
(
booking
.
cleaning
));
}
this
.
addControl
(
BookingFCN
.
state
,
new
FormControl
(
booking
.
state
));
}
api
()
{
const
doc
:
IBooking
=
{
id
:
this
.
id
,
month
:
this
.
month
,
state
:
this
.
stateFC
.
value
,
amount
:
this
.
amountFC
.
value
,
platform
:
this
.
platformFC
.
value
,
range
:
this
.
rangeCtrl
.
api
(),
guest
:
this
.
guestCtrl
.
api
(),
cleaning
:
this
.
cleaningCtrl
?
this
.
cleaningCtrl
.
api
()
:
undefined
,
};
return
doc
;
}
get
cleaningCtrl
()
{
return
this
.
get
(
BookingFCN
.
cleaning
)
as
CleaningCtrl
|
undefined
;
}
set
cleaningCtrl
(
control
:
CleaningCtrl
|
undefined
)
{
if
(
this
.
cleaningCtrl
&&
control
)
{
this
.
setControl
(
BookingFCN
.
cleaning
,
control
);
}
else
if
(
control
)
{
this
.
addControl
(
BookingFCN
.
cleaning
,
control
);
}
else
{
this
.
removeControl
(
BookingFCN
.
cleaning
);
}
}
get
stateFC
()
{
return
this
.
get
(
BookingFCN
.
state
)
as
FormControl
;
}
set
stateFC
(
control
:
FormControl
)
{
this
.
setControl
(
BookingFCN
.
state
,
control
);
}
}
ngx/src/app/controls/calendar.control.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable no-shadow */
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
ICalendar
}
from
'
../api/users.api
'
;
// export class Calendar implements ICalendar {
// summary: string = '';
// id: string = '';
// }
export
class
CalendarCtrl
extends
FormGroup
{
constructor
(
calendar
:
ICalendar
)
{
super
({});
this
.
addControl
(
CalendarFCN
.
summary
,
new
FormControl
(
calendar
.
summary
));
this
.
addControl
(
CalendarFCN
.
id
,
new
FormControl
(
calendar
.
id
));
}
get
idFC
()
{
return
this
.
get
(
CalendarFCN
.
id
)
as
FormControl
;
}
set
idFC
(
control
:
FormControl
)
{
this
.
setControl
(
CalendarFCN
.
id
,
control
);
}
get
summaryFC
()
{
return
this
.
get
(
CalendarFCN
.
summary
)
as
FormControl
;
}
set
summaryFC
(
control
:
FormControl
)
{
this
.
setControl
(
CalendarFCN
.
summary
,
control
);
}
api
()
{
const
calendar
:
ICalendar
=
{
summary
:
this
.
summaryFC
.
value
,
id
:
this
.
idFC
.
value
,
};
return
calendar
;
}
}
enum
CalendarFCN
{
id
=
'
id
'
,
summary
=
'
summary
'
,
}
ngx/src/app/controls/cleaner.control.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
ICleaner
}
from
'
../api/users.api
'
;
export
const
DEFAULT_CLEANER_NAME
=
'
greenchap94@gmail.com
'
;
export
const
DEFAULT_CLEANER
:
ICleaner
=
{
email
:
DEFAULT_CLEANER_NAME
,
rate
:
10
,
name
:
'
test cleaner
'
,
default
:
true
};
export
class
Cleaner
implements
ICleaner
{
rate
:
number
;
name
:
string
;
email
:
string
;
default
:
boolean
;
constructor
(
iCleaner
:
ICleaner
)
{
this
.
rate
=
iCleaner
.
rate
;
this
.
email
=
iCleaner
.
email
;
this
.
name
=
iCleaner
.
name
;
this
.
default
=
iCleaner
.
default
;
}
}
export
class
CleanerCtrl
extends
FormGroup
{
constructor
(
cleaner
:
Cleaner
)
{
super
({});
this
.
addControl
(
CleanerFCN
.
rate
,
new
FormControl
(
cleaner
.
rate
));
this
.
addControl
(
CleanerFCN
.
email
,
new
FormControl
(
cleaner
.
email
));
this
.
addControl
(
CleanerFCN
.
name
,
new
FormControl
(
cleaner
.
name
));
this
.
addControl
(
CleanerFCN
.
default
,
new
FormControl
(
cleaner
.
default
));
}
static
newCleanerCtrl
()
{
return
new
CleanerCtrl
(
DEFAULT_CLEANER
);
}
get
rateFC
()
{
return
this
.
get
(
CleanerFCN
.
rate
)
as
FormControl
;
}
set
rateFC
(
control
:
FormControl
)
{
this
.
setControl
(
CleanerFCN
.
rate
,
control
);
}
get
emailFC
()
{
return
this
.
get
(
CleanerFCN
.
email
)
as
FormControl
;
}
set
emailFC
(
control
:
FormControl
)
{
this
.
setControl
(
CleanerFCN
.
email
,
control
);
}
get
nameFC
()
{
return
this
.
get
(
CleanerFCN
.
name
)
as
FormControl
;
}
set
nameFC
(
control
:
FormControl
)
{
this
.
setControl
(
CleanerFCN
.
name
,
control
);
}
get
defaultFC
()
{
return
this
.
get
(
CleanerFCN
.
default
)
as
FormControl
;
}
set
defaultFC
(
control
:
FormControl
)
{
this
.
setControl
(
CleanerFCN
.
default
,
control
);
}
api
()
{
const
cleaner
:
ICleaner
=
{
rate
:
this
.
rateFC
.
value
,
email
:
this
.
emailFC
.
value
,
name
:
this
.
nameFC
.
value
,
default
:
this
.
defaultFC
.
value
};
return
cleaner
;
}
}
enum
CleanerFCN
{
rate
=
'
rate
'
,
email
=
'
email
'
,
name
=
'
name
'
,
default
=
'
default
'
,
}
ngx/src/app/controls/cleaning.control.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
ICleaning
}
from
'
../api/bookings.api
'
;
export
class
Cleaning
implements
ICleaning
{
cleanerEmail
:
string
;
hours
:
number
;
constructor
(
iCleaning
:
ICleaning
)
{
this
.
cleanerEmail
=
iCleaning
.
cleanerEmail
;
this
.
hours
=
iCleaning
.
hours
;
}
}
export
class
CleaningCtrl
extends
FormGroup
{
hours
:
number
;
constructor
(
cleaning
:
ICleaning
)
{
super
({});
this
.
hours
=
cleaning
.
hours
;
this
.
addControl
(
CleaningFCN
.
cleaner
,
new
FormControl
(
cleaning
.
cleanerEmail
));
}
get
cleanerEmailFC
()
{
return
this
.
get
(
CleaningFCN
.
cleaner
)
as
FormControl
;
}
set
cleanerEmailFC
(
control
:
FormControl
)
{
this
.
setControl
(
CleaningFCN
.
cleaner
,
control
);
}
api
()
{
const
cleaning
:
ICleaning
=
{
hours
:
this
.
hours
,
cleanerEmail
:
this
.
cleanerEmailFC
.
value
,
};
return
cleaning
;
}
}
enum
CleaningFCN
{
cleaner
=
'
cleaner
'
,
}
ngx/src/app/controls/command.control.ts
0 → 100644
View file @
51362d9c
/* eslint-disable no-shadow */
import
{
FormArray
,
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
ICommand
}
from
'
../api/commands.api
'
;
import
{
OptionCtrl
}
from
'
./option.control
'
;
const
enum
CommandFCN
{
name
=
'
name
'
,
options
=
'
options
'
,
}
export
class
CommandCtrl
extends
FormGroup
{
constructor
(
icommand
:
ICommand
)
{
super
({});
this
.
addControl
(
CommandFCN
.
name
,
new
FormControl
(
icommand
.
name
));
this
.
addControl
(
CommandFCN
.
options
,
new
FormArray
(
icommand
.
options
.
map
((
ioption
)
=>
new
OptionCtrl
(
ioption
))));
}
api
()
{
const
doc
:
ICommand
=
{
name
:
this
.
nameFC
.
value
,
options
:
this
.
optionsFA
.
controls
.
map
(
control
=>
(
control
as
OptionCtrl
).
api
()),
};
return
doc
;
}
get
nameFC
()
{
return
this
.
get
(
CommandFCN
.
name
)
as
FormControl
;
}
set
nameFC
(
control
:
FormControl
)
{
this
.
setControl
(
CommandFCN
.
name
,
control
);
}
get
optionsFA
()
{
return
this
.
get
(
CommandFCN
.
options
)
as
FormArray
;
}
set
optionsFA
(
control
:
FormArray
)
{
this
.
setControl
(
CommandFCN
.
options
,
control
);
}
}
ngx/src/app/controls/guest.control.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
IGuest
}
from
'
../api/bookings.api
'
;
export
class
Guest
{
given
:
string
;
email
:
string
;
constructor
(
iGuest
:
IGuest
)
{
this
.
given
=
iGuest
.
given
;
this
.
email
=
iGuest
.
email
;
}
}
export
class
GuestCtrl
extends
FormGroup
{
constructor
(
guest
:
Guest
)
{
super
({});
this
.
addControl
(
GuestFCN
.
given
,
new
FormControl
(
guest
.
given
));
this
.
addControl
(
GuestFCN
.
email
,
new
FormControl
(
guest
.
email
));
}
get
givenFC
()
{
return
this
.
get
(
GuestFCN
.
given
)
as
FormControl
;
}
set
givenFC
(
control
:
FormControl
)
{
this
.
setControl
(
GuestFCN
.
given
,
control
);
}
get
emailFC
()
{
return
this
.
get
(
GuestFCN
.
email
)
as
FormControl
;
}
set
emailFC
(
control
:
FormControl
)
{
this
.
setControl
(
GuestFCN
.
email
,
control
);
}
api
()
{
const
guest
:
IGuest
=
{
given
:
this
.
givenFC
.
value
,
email
:
this
.
emailFC
.
value
,
};
return
guest
;
}
}
enum
GuestFCN
{
given
=
'
given
'
,
email
=
'
email
'
,
}
ngx/src/app/controls/message.control.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable no-shadow */
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
IMessage
,
ISubject
}
from
'
../api/users.api
'
;
// export class Message implements IMessage {
// subject: ISubject;
// body: string;
// }
export
class
MessageCtrl
extends
FormGroup
{
subject
:
ISubject
;
constructor
(
message
:
IMessage
)
{
super
({});
this
.
subject
=
message
.
subject
;
this
.
addControl
(
MessageFCN
.
body
,
new
FormControl
(
message
.
body
.
replace
(
/<br
\s
*
[\/]?
>/gi
,
'
\n
'
)));
}
static
newMessageCtrl
()
{
const
iMessage
:
IMessage
=
{
subject
:
ISubject
.
WELCOME
,
body
:
'
how are you ?
'
,
};
return
new
MessageCtrl
(
iMessage
);
}
get
bodyFC
()
{
return
this
.
get
(
MessageFCN
.
body
)
as
FormControl
;
}
set
bodyFC
(
control
:
FormControl
)
{
this
.
setControl
(
MessageFCN
.
body
,
control
);
}
api
()
{
const
message
:
IMessage
=
{
subject
:
this
.
subject
,
body
:
this
.
bodyFC
.
value
,
};
return
message
;
}
}
enum
MessageFCN
{
body
=
'
body
'
,
}
ngx/src/app/controls/newbooking.control.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable no-shadow */
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
INewBooking
,
IPlatform
}
from
'
../api/bookings.api
'
;
import
{
Guest
,
GuestCtrl
}
from
'
./guest.control
'
;
import
{
Range
,
RangeCtrl
}
from
'
./range.control
'
;
const
enum
NewBookingFCN
{
guest
=
'
guest
'
,
amount
=
'
amount
'
,
platform
=
'
platform
'
,
range
=
'
range
'
}
export
class
NewBooking
{
amount
:
number
;
platform
:
IPlatform
;
guest
:
Guest
;
range
:
Range
;
constructor
(
iNewBooking
:
INewBooking
)
{
this
.
amount
=
iNewBooking
.
amount
!
;
this
.
platform
=
iNewBooking
.
platform
!
;
this
.
range
=
new
Range
(
iNewBooking
.
range
!
);
this
.
guest
=
new
Guest
(
iNewBooking
.
guest
!
);
}
}
export
class
NewBookingCtrl
extends
FormGroup
{
constructor
(
inewbooking
:
INewBooking
)
{
super
({});
const
newbooking
=
new
NewBooking
(
inewbooking
);
this
.
addControl
(
NewBookingFCN
.
amount
,
new
FormControl
(
newbooking
.
amount
));
this
.
addControl
(
NewBookingFCN
.
platform
,
new
FormControl
(
newbooking
.
platform
));
this
.
addControl
(
NewBookingFCN
.
range
,
new
RangeCtrl
(
newbooking
.
range
));
this
.
addControl
(
NewBookingFCN
.
guest
,
new
GuestCtrl
(
newbooking
.
guest
));
}
api
()
{
const
doc
:
INewBooking
=
{
amount
:
this
.
amountFC
.
value
,
platform
:
this
.
platformFC
.
value
,
range
:
this
.
rangeCtrl
.
api
(),
guest
:
this
.
guestCtrl
.
api
(),
};
return
doc
;
}
get
guestCtrl
()
{
return
this
.
get
(
NewBookingFCN
.
guest
)
as
GuestCtrl
;
}
set
guestCtrl
(
control
:
GuestCtrl
)
{
this
.
setControl
(
NewBookingFCN
.
guest
,
control
);
}
get
rangeCtrl
()
{
return
this
.
get
(
NewBookingFCN
.
range
)
as
RangeCtrl
;
}
set
rangeCtrl
(
control
:
RangeCtrl
)
{
this
.
setControl
(
NewBookingFCN
.
range
,
control
);
}
get
amountFC
()
{
return
this
.
get
(
NewBookingFCN
.
amount
)
as
FormControl
;
}
set
amountFC
(
control
:
FormControl
)
{
this
.
setControl
(
NewBookingFCN
.
amount
,
control
);
}
get
platformFC
()
{
return
this
.
get
(
NewBookingFCN
.
platform
)
as
FormControl
;
}
set
platformFC
(
control
:
FormControl
)
{
this
.
setControl
(
NewBookingFCN
.
platform
,
control
);
}
get
shortName
()
{
return
this
.
guestCtrl
.
givenFC
.
value
+
'
(
'
+
this
.
platformFC
.
value
+
'
)
'
;
}
}
ngx/src/app/controls/option.control.ts
0 → 100644
View file @
51362d9c
/* eslint-disable no-shadow */
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
IOption
}
from
'
../api/commands.api
'
;
const
enum
OptionFCN
{
key
=
'
key
'
,
value
=
'
value
'
,
}
export
class
Option
{
key
:
string
;
value
:
number
;
constructor
(
ioption
:
IOption
)
{
this
.
key
=
ioption
.
key
;
this
.
value
=
ioption
.
value
;
}
}
export
class
OptionCtrl
extends
FormGroup
{
constructor
(
ioption
:
IOption
)
{
super
({});
const
option
=
new
Option
(
ioption
);
this
.
addControl
(
OptionFCN
.
key
,
new
FormControl
(
option
.
key
));
this
.
addControl
(
OptionFCN
.
value
,
new
FormControl
(
option
.
value
));
}
api
()
{
const
doc
:
IOption
=
{
key
:
this
.
keyFC
.
value
,
value
:
this
.
valueFC
.
value
,
};
return
doc
;
}
get
keyFC
()
{
return
this
.
get
(
OptionFCN
.
key
)
as
FormControl
;
}
set
keyFC
(
control
:
FormControl
)
{
this
.
setControl
(
OptionFCN
.
key
,
control
);
}
get
valueFC
()
{
return
this
.
get
(
OptionFCN
.
value
)
as
FormControl
;
}
setvalueFC
(
control
:
FormControl
)
{
this
.
setControl
(
OptionFCN
.
value
,
control
);
}
}
ngx/src/app/controls/range.control.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
*
as
moment
from
'
moment
'
;
import
{
IRange
}
from
'
../api/bookings.api
'
;
export
class
Range
{
startDay
:
Date
;
endDay
:
Date
;
checkin
:
string
;
checkout
:
string
;
constructor
(
iRange
:
IRange
)
{
this
.
startDay
=
moment
(
iRange
.
start
).
local
().
toDate
();
this
.
endDay
=
moment
(
iRange
.
end
).
local
().
toDate
();
this
.
checkin
=
moment
(
iRange
.
start
).
local
().
format
(
'
HH:mm
'
);
this
.
checkout
=
moment
(
iRange
.
end
).
local
().
format
(
'
HH:mm
'
);
}
}
export
class
RangeCtrl
extends
FormGroup
{
constructor
(
range
:
Range
)
{
super
({});
this
.
addControl
(
RangeFCN
.
startDay
,
new
FormControl
(
range
.
startDay
));
this
.
addControl
(
RangeFCN
.
endDay
,
new
FormControl
(
range
.
endDay
));
this
.
addControl
(
RangeFCN
.
checkin
,
new
FormControl
(
range
.
checkin
));
this
.
addControl
(
RangeFCN
.
checkout
,
new
FormControl
(
range
.
checkout
));
}
get
startDayFC
()
{
return
this
.
get
(
RangeFCN
.
startDay
)
as
FormControl
;
}
set
startDayFC
(
control
:
FormControl
)
{
this
.
setControl
(
RangeFCN
.
startDay
,
control
);
}
get
endDayFC
()
{
return
this
.
get
(
RangeFCN
.
endDay
)
as
FormControl
;
}
set
endDayFC
(
control
:
FormControl
)
{
this
.
setControl
(
RangeFCN
.
endDay
,
control
);
}
get
checkinFC
()
{
return
this
.
get
(
RangeFCN
.
checkin
)
as
FormControl
;
}
set
checkinFC
(
control
:
FormControl
)
{
this
.
setControl
(
RangeFCN
.
checkin
,
control
);
// TODO update booking state when specifying checkin hour
}
get
checkoutFC
()
{
return
this
.
get
(
RangeFCN
.
checkout
)
as
FormControl
;
}
set
checkoutFC
(
control
:
FormControl
)
{
this
.
setControl
(
RangeFCN
.
checkout
,
control
);
// TODO update booking state when specifying checkin hour
}
api
()
{
const
checkin
=
moment
(
this
.
checkinFC
.
value
,
'
LTS
'
);
const
start
=
moment
(
this
.
startDayFC
.
value
).
set
({
hour
:
checkin
.
get
(
'
hour
'
),
minute
:
checkin
.
get
(
'
minute
'
),
});
const
checkout
=
moment
(
this
.
checkoutFC
.
value
,
'
LTS
'
);
const
end
=
moment
(
this
.
endDayFC
.
value
).
set
({
hour
:
checkout
.
get
(
'
hour
'
),
minute
:
checkout
.
get
(
'
minute
'
),
});
const
range
:
IRange
=
{
start
:
start
.
format
(),
end
:
end
.
format
(),
};
return
range
;
}
}
enum
RangeFCN
{
startDay
=
'
start
'
,
endDay
=
'
end
'
,
checkin
=
'
checkin
'
,
checkout
=
'
checkout
'
,
}
ngx/src/app/controls/user.control.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
FormArray
,
FormControl
,
FormGroup
}
from
'
@angular/forms
'
;
import
{
IUser
}
from
'
../api/users.api
'
;
import
{
CalendarCtrl
}
from
'
./calendar.control
'
;
import
{
CleanerCtrl
}
from
'
./cleaner.control
'
;
import
{
MessageCtrl
}
from
'
./message.control
'
;
// export class User implements IUser {
// subjectPrefix: string;
// busyCal: ICalendar;
// cleaningCal: ICalendar;
// reelCal: ICalendar;
// address: string
// messages : Message[]
// cleaners : Cleaner[]
// isRegistered : boolean
// autoSend : boolean
// name: string
// tel: string
// }
export
class
UserCtrl
extends
FormGroup
{
isRegistered
:
boolean
;
constructor
(
iuser
:
IUser
)
{
super
({});
this
.
isRegistered
=
iuser
.
isRegistered
;
this
.
addControl
(
UserFCN
.
busyCal
,
new
CalendarCtrl
(
iuser
.
busyCal
));
this
.
addControl
(
UserFCN
.
cleaningCal
,
new
CalendarCtrl
(
iuser
.
cleaningCal
));
this
.
addControl
(
UserFCN
.
reelCal
,
new
CalendarCtrl
(
iuser
.
reelCal
));
this
.
addControl
(
UserFCN
.
subjectPrefix
,
new
FormControl
(
iuser
.
subjectPrefix
));
this
.
addControl
(
UserFCN
.
address
,
new
FormControl
(
iuser
.
address
));
this
.
addControl
(
UserFCN
.
name
,
new
FormControl
(
iuser
.
name
));
this
.
addControl
(
UserFCN
.
tel
,
new
FormControl
(
iuser
.
tel
));
this
.
addControl
(
UserFCN
.
defaultCheckInHour
,
new
FormControl
(
iuser
.
defaultCheckInHour
));
this
.
addControl
(
UserFCN
.
defaultCheckOutHour
,
new
FormControl
(
iuser
.
defaultCheckOutHour
));
this
.
addControl
(
UserFCN
.
defaultCleaningHours
,
new
FormControl
(
iuser
.
defaultCleaningHours
));
this
.
addControl
(
UserFCN
.
messages
,
new
FormArray
(
iuser
.
messages
.
map
((
imessage
)
=>
new
MessageCtrl
(
imessage
))));
this
.
addControl
(
UserFCN
.
cleaners
,
new
FormArray
(
iuser
.
cleaners
.
map
((
icleaner
)
=>
new
CleanerCtrl
(
icleaner
))));
this
.
addControl
(
UserFCN
.
autoSend
,
new
FormControl
(
iuser
.
autoSend
));
}
get
subjectPrefixFC
()
{
return
this
.
get
(
UserFCN
.
subjectPrefix
)
as
FormControl
;
}
set
subjectPrefixFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
subjectPrefix
,
control
);
}
get
defaultCheckInHourFC
()
{
return
this
.
get
(
UserFCN
.
defaultCheckInHour
)
as
FormControl
;
}
set
defaultCheckInHourFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
defaultCheckInHour
,
control
);
}
get
defaultCleaningHoursFC
()
{
return
this
.
get
(
UserFCN
.
defaultCleaningHours
)
as
FormControl
;
}
set
defaultCleaningHoursFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
defaultCleaningHours
,
control
);
}
get
defaultCheckOutHourFC
()
{
return
this
.
get
(
UserFCN
.
defaultCheckOutHour
)
as
FormControl
;
}
set
defaultCheckOutHourFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
defaultCheckOutHour
,
control
);
}
get
busyCalCtrl
()
{
return
this
.
get
(
UserFCN
.
busyCal
)
as
CalendarCtrl
;
}
set
busyCalCtrl
(
control
:
CalendarCtrl
)
{
this
.
setControl
(
UserFCN
.
busyCal
,
control
);
}
get
cleaningCalCtrl
()
{
return
this
.
get
(
UserFCN
.
cleaningCal
)
as
CalendarCtrl
;
}
set
cleaningCalCtrl
(
control
:
CalendarCtrl
)
{
this
.
setControl
(
UserFCN
.
cleaningCal
,
control
);
}
get
reelCalCtrl
()
{
return
this
.
get
(
UserFCN
.
reelCal
)
as
CalendarCtrl
;
}
set
reelCalCtrl
(
control
:
CalendarCtrl
)
{
this
.
setControl
(
UserFCN
.
reelCal
,
control
);
}
get
nameFC
()
{
return
this
.
get
(
UserFCN
.
name
)
as
FormControl
;
}
set
nameFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
name
,
control
);
}
get
telFC
()
{
return
this
.
get
(
UserFCN
.
tel
)
as
FormControl
;
}
set
telFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
tel
,
control
);
}
get
addressFC
()
{
return
this
.
get
(
UserFCN
.
address
)
as
FormControl
;
}
set
addressFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
address
,
control
);
}
get
messagesFA
()
{
return
this
.
get
(
UserFCN
.
messages
)
as
FormArray
;
}
set
messagesFA
(
fa
:
FormArray
)
{
this
.
setControl
(
UserFCN
.
messages
,
fa
);
}
get
cleanersFA
()
{
return
this
.
get
(
UserFCN
.
cleaners
)
as
FormArray
;
}
set
cleanersFA
(
fa
:
FormArray
)
{
this
.
setControl
(
UserFCN
.
cleaners
,
fa
);
}
get
autoSendFC
()
{
return
this
.
get
(
UserFCN
.
autoSend
)
as
FormControl
;
}
set
autoSendFC
(
control
:
FormControl
)
{
this
.
setControl
(
UserFCN
.
autoSend
,
control
);
}
api
()
{
const
config
:
IUser
=
{
subjectPrefix
:
this
.
subjectPrefixFC
.
value
,
defaultCheckInHour
:
this
.
defaultCheckInHourFC
.
value
,
defaultCleaningHours
:
this
.
defaultCleaningHoursFC
.
value
,
defaultCheckOutHour
:
this
.
defaultCheckOutHourFC
.
value
,
busyCal
:
this
.
busyCalCtrl
.
value
,
cleaningCal
:
this
.
cleaningCalCtrl
.
value
,
reelCal
:
this
.
reelCalCtrl
.
value
,
address
:
this
.
addressFC
.
value
,
name
:
this
.
nameFC
.
value
,
tel
:
this
.
telFC
.
value
,
messages
:
this
.
messagesFA
.
controls
.
map
((
control
)
=>
(
control
as
MessageCtrl
).
api
()),
cleaners
:
this
.
cleanersFA
.
controls
.
map
((
control
)
=>
(
control
as
CleanerCtrl
).
api
()),
isRegistered
:
this
.
isRegistered
,
autoSend
:
this
.
autoSendFC
.
value
,
};
return
config
;
}
}
enum
UserFCN
{
subjectPrefix
=
'
subjectPrefix
'
,
defaultCheckOutHour
=
'
defaultCheckOutHour
'
,
defaultCleaningHours
=
'
defaultCleaningHours
'
,
defaultCheckInHour
=
'
defaultCheckInHour
'
,
busyCal
=
'
busyCal
'
,
cleaningCal
=
'
cleaningCal
'
,
reelCal
=
'
reelCal
'
,
address
=
'
address
'
,
name
=
'
name
'
,
tel
=
'
tel
'
,
messages
=
'
messages
'
,
cleaners
=
'
cleaners
'
,
autoSend
=
'
autoSend
'
,
}
ngx/src/app/guards/auth.guard.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
ActivatedRouteSnapshot
,
CanActivate
,
RouterStateSnapshot
}
from
'
@angular/router
'
;
import
{
Observable
}
from
'
rxjs
'
;
import
{
tap
}
from
'
rxjs/operators
'
;
import
{
UserService
}
from
'
src/app/services/user.service
'
;
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
AuthGuard
implements
CanActivate
{
constructor
(
private
userService
:
UserService
)
{
}
canActivate
(
next
:
ActivatedRouteSnapshot
,
state
:
RouterStateSnapshot
)
{
return
this
.
userService
.
isAuthenticated$
.
pipe
(
tap
((
x
)
=>
console
.
log
(
'
You tried to go to
'
+
state
.
url
+
'
and AuthGuard said
'
+
x
)));
}
}
ngx/src/app/interceptors/interceptors.ts
View file @
51362d9c
import
{
HTTP_INTERCEPTORS
}
from
'
@angular/common/http
'
;
import
{
ErrorInterceptor
}
from
'
./error.interceptor
'
;
import
{
SpinnerInterceptor
}
from
'
./spinner.interceptor
'
;
import
{
TokenInterceptor
}
from
'
./token.interceptor
'
;
export
const
InterceptorProviders
=
[
{
provide
:
HTTP_INTERCEPTORS
,
useClass
:
TokenInterceptor
,
multi
:
true
},
{
provide
:
HTTP_INTERCEPTORS
,
useClass
:
SpinnerInterceptor
,
multi
:
true
},
{
provide
:
HTTP_INTERCEPTORS
,
useClass
:
ErrorInterceptor
,
multi
:
true
},
];
ngx/src/app/interceptors/token.interceptor.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable @typescript-eslint/naming-convention */
import
{
HttpEvent
,
HttpHandler
,
HttpHeaders
,
HttpInterceptor
,
HttpRequest
}
from
'
@angular/common/http
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
Observable
}
from
'
rxjs
'
;
import
{
UserService
}
from
'
../services/user.service
'
;
@
Injectable
()
export
class
TokenInterceptor
implements
HttpInterceptor
{
constructor
(
public
userService
:
UserService
)
{
}
intercept
(
request
:
HttpRequest
<
any
>
,
next
:
HttpHandler
)
{
const
accessToken
=
this
.
userService
.
accessToken
!
;
const
idToken
=
this
.
userService
.
idToken
!
;
// Clone the request and set the new header in one step.
const
authReq
=
request
.
clone
({
setHeaders
:
{
'
Content-Type
'
:
'
application/json
'
,
'
access-token
'
:
accessToken
,
'
id-token
'
:
idToken
,
},
});
console
.
error
(
request
.
method
+
'
'
+
request
.
url
);
// send cloned request with header to the next handler.
return
next
.
handle
(
authReq
);
}
}
ngx/src/app/services/dialog.service.ts
View file @
51362d9c
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
MatDialog
}
from
'
@angular/material/dialog
'
;
import
{
MatSnackBar
}
from
'
@angular/material/snack-bar
'
;
import
{
of
}
from
'
rxjs
'
;
import
{
tap
}
from
'
rxjs/operators
'
;
import
{
ErrorDialogComponent
}
from
'
../components/error-dialog/error-dialog.component
'
;
import
{
NewBookingDialogComponent
}
from
'
../components/new-booking-dialog/new-booking.component
'
;
import
{
NewBookingCtrl
}
from
'
../controls/newbooking.control
'
;
@
Injectable
({
providedIn
:
'
root
'
,
...
...
@@ -36,22 +32,6 @@ export class DialogService {
});
}
openNewBookingDialog$
(
control
:
NewBookingCtrl
)
{
if
(
this
.
isDialogOpen
)
{
return
of
(
undefined
);
}
this
.
isDialogOpen
=
true
;
const
dialogRef
=
this
.
_dialog
.
open
(
NewBookingDialogComponent
,
{
width
:
'
800px
'
,
data
:
control
,
restoreFocus
:
false
});
return
dialogRef
.
afterClosed
().
pipe
(
tap
(()
=>
this
.
isDialogOpen
=
false
));
}
openSnackBar
(
title
:
string
):
void
{
this
.
_snackBar
.
open
(
title
,
undefined
,
{
duration
:
500
,
...
...
ngx/src/app/services/user.service.ts
deleted
100644 → 0
View file @
8ead6ae7
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
AngularFireAuth
}
from
'
@angular/fire/compat/auth/
'
;
import
{
Router
}
from
'
@angular/router
'
;
import
firebase
from
'
firebase/compat/app
'
;
import
{
BehaviorSubject
}
from
'
rxjs
'
;
import
{
map
,
tap
}
from
'
rxjs/operators
'
;
import
{
UsersApi
}
from
'
../api/users.api
'
;
import
{
UserCtrl
}
from
'
../controls/user.control
'
;
import
{
WorkerService
}
from
'
./worker.service
'
;
const
USER_SCOPES
=
[
'
https://mail.google.com/
'
,
'
https://www.googleapis.com/auth/gmail.modify
'
,
'
https://www.googleapis.com/auth/gmail.compose
'
,
'
https://www.googleapis.com/auth/gmail.send
'
,
'
https://www.googleapis.com/auth/calendar
'
,
'
https://www.googleapis.com/auth/contacts
'
,
'
https://www.googleapis.com/auth/drive
'
,
];
export
const
FIREBASE
=
{
apiKey
:
'
AIzaSyC5d_2nWqOViYzJltaOKKgCS9RR7aABYZg
'
,
authDomain
:
'
serema-2d3df.firebaseapp.com
'
,
databaseURL
:
'
https://serema-2d3df.firebaseio.com
'
,
projectId
:
'
serema-2d3df
'
,
storageBucket
:
'
serema-2d3df.appspot.com
'
,
messagingSenderId
:
'
126536035414
'
,
appId
:
'
1:126536035414:web:fa50b91256a64a3d9f9ff7
'
,
measurementId
:
'
G-LRC0R7PPJQ
'
,
};
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
UserService
{
public
isAuthenticated$
=
new
BehaviorSubject
<
boolean
>
(
false
);
public
userCtrl$
=
new
BehaviorSubject
<
UserCtrl
|
undefined
>
(
undefined
);
constructor
(
public
afa
:
AngularFireAuth
,
public
usersApi
:
UsersApi
,
public
router
:
Router
,
public
workerService
:
WorkerService
)
{
}
get
isRegistered$
()
{
return
this
.
userCtrl$
.
pipe
(
map
((
userCtrl
)
=>
(
userCtrl
?
userCtrl
.
isRegistered
:
undefined
)));
}
get
userCtrl
()
{
return
this
.
userCtrl$
.
getValue
();
}
public
register
()
{
this
.
workerService
.
loginRedirect
();
}
public
unregister
()
{
this
.
workerService
.
logout
();
const
userCtrl
=
this
.
userCtrl$
.
getValue
();
if
(
userCtrl
)
{
userCtrl
.
isRegistered
=
false
;
userCtrl
.
autoSendFC
.
setValue
(
false
);
this
.
update$
(
userCtrl
).
subscribe
((
_
)
=>
{
this
.
userCtrl$
.
next
(
userCtrl
);
});
}
else
{
// TODO
}
}
public
onRegisterSuccess
()
{
this
.
workerService
.
loginRedirectCallback
();
const
userCtrl
=
this
.
userCtrl
;
if
(
userCtrl
)
{
userCtrl
.
isRegistered
=
true
;
this
.
userCtrl$
.
next
(
userCtrl
);
}
else
{
// TODO
}
}
public
login
()
{
const
provider
=
new
firebase
.
auth
.
GoogleAuthProvider
();
USER_SCOPES
.
forEach
((
scope
)
=>
provider
.
addScope
(
scope
));
// POPUP
return
this
.
afa
.
signInWithPopup
(
provider
)
.
then
((
result
)
=>
{
this
.
isAuthenticated$
.
next
(
true
);
localStorage
.
setItem
(
'
authResult
'
,
JSON
.
stringify
(
result
));
this
.
usersApi
.
read$
()
.
pipe
(
map
((
iuser
)
=>
new
UserCtrl
(
iuser
)))
.
subscribe
((
userCtrl
)
=>
{
this
.
userCtrl$
=
new
BehaviorSubject
<
UserCtrl
|
undefined
>
(
userCtrl
);
this
.
router
.
navigate
([
'
/bookings
'
]);
});
})
.
catch
((
error
)
=>
{
window
.
alert
(
error
);
});
}
public
logout
()
{
return
this
.
afa
.
signOut
().
then
(()
=>
{
localStorage
.
removeItem
(
'
authResult
'
);
this
.
isAuthenticated$
.
next
(
false
);
this
.
router
.
navigate
([
'
/
'
]);
});
}
private
get
authResult
()
{
const
authResult
=
localStorage
.
getItem
(
'
authResult
'
);
if
(
authResult
)
{
return
JSON
.
parse
(
authResult
);
}
else
{
return
undefined
;
}
}
get
email
()
{
return
this
.
authResult
?
this
.
authResult
.
user
.
email
:
undefined
;
}
get
accessToken
()
{
return
this
.
authResult
?
this
.
authResult
.
credential
.
accessToken
:
undefined
;
}
get
idToken
()
{
return
this
.
authResult
?
this
.
authResult
.
credential
.
idToken
:
undefined
;
}
read$
()
{
this
.
userCtrl$
.
next
(
undefined
);
return
this
.
usersApi
.
read$
().
pipe
(
map
((
iuser
)
=>
new
UserCtrl
(
iuser
)),
tap
((
userCtrl
)
=>
this
.
userCtrl$
.
next
(
userCtrl
)),
);
}
refresh$
()
{
this
.
userCtrl$
.
next
(
undefined
);
return
this
.
usersApi
.
refresh$
().
pipe
(
map
((
iuser
)
=>
new
UserCtrl
(
iuser
)),
tap
((
userCtrl
)
=>
this
.
userCtrl$
.
next
(
userCtrl
)),
);
}
update$
(
userCtrl
:
UserCtrl
)
{
this
.
userCtrl$
.
next
(
undefined
);
return
this
.
usersApi
.
update$
(
userCtrl
.
api
()).
pipe
(
tap
((
_
)
=>
this
.
userCtrl$
.
next
(
userCtrl
)));
}
}
ngx/src/app/services/worker.service.ts
deleted
100644 → 0
View file @
8ead6ae7
/* eslint-disable @typescript-eslint/naming-convention */
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
GoogleAuthService
,
NgGapiClientConfig
}
from
'
ng-gapi
'
;
import
{
environment
}
from
'
src/environments/environment
'
;
import
{
AutoSendApi
}
from
'
../api/autosend.api
'
;
import
GoogleUser
=
gapi
.
auth2
.
GoogleUser
;
const
WORKER_SCOPES
=
[
'
https://mail.google.com/
'
,
'
https://www.googleapis.com/auth/gmail.modify
'
,
'
https://www.googleapis.com/auth/gmail.compose
'
,
'
https://www.googleapis.com/auth/gmail.send
'
,
'
https://www.googleapis.com/auth/calendar
'
,
'
https://www.googleapis.com/auth/contacts
'
,
'
https://www.googleapis.com/auth/drive
'
,
];
export
const
gapiClientConfig
:
NgGapiClientConfig
=
{
discoveryDocs
:
[
'
https://analyticsreporting.googleapis.com/$discovery/rest?version=v4
'
],
/**
* The app's client ID, found and created in the Google Developers Console.
*/
// client_id?: string;
client_id
:
environment
.
WORKER_CLIENT_ID
,
/**
* The domains for which to create sign-in cookies. Either a URI, single_host_origin, or none.
* Defaults to single_host_origin if unspecified.
*/
// cookie_policy: ,
/**
* The scopes to request, as a space-delimited string. Optional if fetch_basic_profile is not set to false.
*/
// scope?: string;
scope
:
WORKER_SCOPES
.
join
(
'
'
),
/**
* Fetch users' basic profile information when they sign in. Adds 'profile' and 'email' to the requested scopes. True if unspecified.
*/
// fetch_basic_profile?: boolean;
/**
* The Google Apps domain to which users must belong to sign in. This is susceptible to modification by clients,
* so be sure to verify the hosted domain property of the returned user. Use GoogleUser.getHostedDomain() on the client,
* and the hd claim in the ID Token on the server to verify the domain is what you expected.
*/
// hosted_domain?: string;
/**
* Used only for OpenID 2.0 client migration. Set to the value of the realm that you are currently using for OpenID 2.0,
* as described in <a href="https://developers.google.com/accounts/docs/OpenID#openid-connect">OpenID 2.0 (Migration)</a>.
*/
// openid_realm?: string;
/**
* The UX mode to use for the sign-in flow.
* By default, it will open the consent flow in a popup.
*/
// ux_mode?: "popup" | "redirect";
ux_mode
:
'
redirect
'
,
/**
* If using ux_mode='redirect', this parameter allows you to override the
* default redirect_uri that will be used at the end of the consent flow.
* The default redirect_uri is the current URL stripped of query parameters and hash fragment.
*/
redirect_uri
:
window
.
location
.
origin
+
'
/oauth2callback
'
,
};
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
WorkerService
{
private
user
?:
GoogleUser
;
constructor
(
private
autosendApi
:
AutoSendApi
,
private
googleAuthService
:
GoogleAuthService
)
{
}
get
email
()
{
return
this
.
user
?
this
.
user
.
getBasicProfile
().
getEmail
()
:
undefined
;
}
// popup
public
loginPopup
()
{
this
.
googleAuthService
.
getAuth
().
subscribe
(
async
(
auth
)
=>
{
this
.
user
=
await
auth
.
signIn
();
});
}
// redirect
public
loginRedirect
()
{
this
.
googleAuthService
.
getAuth
().
subscribe
(
async
(
auth
)
=>
{
const
{
code
}
=
await
auth
.
grantOfflineAccess
();
this
.
autosendApi
.
register$
(
code
).
subscribe
();
});
}
public
loginRedirectCallback
()
{
this
.
googleAuthService
.
getAuth
().
subscribe
((
auth
)
=>
{
this
.
user
=
auth
.
currentUser
.
get
();
});
}
public
logout
()
{
this
.
googleAuthService
.
getAuth
().
subscribe
((
auth
)
=>
{
auth
.
signOut
();
});
}
}
ngx/src/environments/environment.prod.ts
View file @
51362d9c
...
...
@@ -4,7 +4,5 @@
export
const
environment
=
{
production
:
true
,
backend
:
'
https://lsd.nutridata.io/api
'
,
// backend: 'https://lsdapi.herokuapp.com',
WORKER_CLIENT_ID
:
'
126536035414-pav49qj5h49rctdrj35ok4amqjnjje1m.apps.googleusercontent.com
'
,
backend
:
'
http://localhost:3000/api
'
//FIXME
};
ngx/src/environments/environment.ts
View file @
51362d9c
...
...
@@ -4,8 +4,7 @@
export
const
environment
=
{
production
:
false
,
backend
:
'
http://localhost:3000/api
'
,
WORKER_CLIENT_ID
:
'
126536035414-pav49qj5h49rctdrj35ok4amqjnjje1m.apps.googleusercontent.com
'
,
backend
:
'
http://localhost:3000/api
'
};
/*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment