Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Mauritz, Falk Marius
SWTII Cal
Commits
cace4417
Commit
cace4417
authored
Jun 19, 2019
by
Mauritz, Falk Marius
Browse files
Merge branch 'AqueductBranch' into 'master'
Aqueduct branch See merge request
!32
parents
b6965f07
29e215d9
Pipeline
#7689
passed with stage
in 3 minutes and 52 seconds
Changes
74
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
cace4417
...
...
@@ -4,7 +4,8 @@ services:
variables
:
DOCKER_HOST
:
tcp://docker:2375
DOCKER_DRIVER
:
overlay2
IMAGE_TAG
:
$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script
:
-
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
...
...
README.md
View file @
cace4417
...
...
@@ -26,12 +26,22 @@ Bitte nur zur lokalen Entwicklung nutzen.
SQL zum erstellen einer Datenbank,
'password' und 'user' nach Wahl.
// entfernt alle aktuellen verbindungen zur db
select pg_terminate_backend(pid) from pg_stat_activity where datname='calendar';
// löscht die Database
DROP DATABASE calendar;
----------------------------------------------
CREATE DATABASE calendar;
CREATE USER cal_user WITH createdb;
ALTER USER cal_user WITH password 'password';
CREATE DATABASE calendar;
GRANT all ON database calendar TO cal_user;
----------------------------------------------
aqueduct auth add-client --id com.calendar.app
// dockercompose
...
...
docker-compose.yml
View file @
cace4417
...
...
@@ -5,7 +5,7 @@ services:
build
:
context
:
.
dockerfile
:
frontend/Dockerfile
dockerfile
:
frontend/Dockerfile
Compose
ports
:
-
"
8080:80"
...
...
@@ -15,20 +15,25 @@ services:
image
:
middleman
build
:
context
:
.
dockerfile
:
middleman/Dockerfile
dockerfile
:
middleman/Dockerfile
Compose
ports
:
-
"
8888:8888"
environment
:
-
CAL_DB_HOST=postgres
-
CAL_DB_PORT=5432
-
CAL_DB_USER=
cal_us
er
-
CAL_DB_USER=
dock
er
-
CAL_DB_NAME=calendar
-
CAL_DB_PASS=
password
-
CAL_DB_PASS=
docker
postgres
:
image
:
postgres
build
:
context
:
.
dockerfile
:
postgres/Dockerfile
ports
:
-
"
5432:5432"
volumes
:
-
./pgdata:/var/lib/postgresql/data
environment
:
POSTGRES_USER
:
docker
POSTGRES_PASSWORD
:
docker
...
...
frontend/DockerfileCompose
0 → 100644
View file @
cace4417
FROM google/dart:2.2 AS builder
ENV PATH="${PATH}:/root/.pub-cache/bin"
WORKDIR /root/build-here
COPY frontend/pubspec.yaml /root/build-here/
RUN pub get
COPY frontend/ /root/build-here/
RUN pub get
RUN pub run build_runner build --output web:build --release
FROM nginx
EXPOSE 80
RUN sed -i -e 's, location / {, location /calendar {,g' /etc/nginx/conf.d/default.conf; \
sed -i -e 's, root /usr/share/nginx/html;, alias /usr/share/nginx/html;,g' /etc/nginx/conf.d/default.conf
COPY --from=builder /root/build-here/build /usr/share/nginx/html
frontend/build.yaml
View file @
cace4417
...
...
@@ -6,13 +6,8 @@ targets:
generate_for
:
-
web/main.dart
options
:
compiler
:
dart2js
# List any dart2js specific args here, or omit it.
dart2js_args
:
-
--minify
-
-O2
-
-Dhost=http://localhost:8888/
release_options
:
compiler
:
dart2js
dart2js_args
:
-
--minify
-
-Dhost=http
s
://
projects.mylab.th-luebeck.de:443/calendar/mm
-
-Dhost=http://
localhost:8888
\ No newline at end of file
frontend/lib/src/model/appointment.dart
View file @
cace4417
class
Appointment
{
// constructor
Appointment
(
this
.
id
,
this
.
contactCodes
,
this
.
name
,
this
.
year
,
this
.
month
,
this
.
day
,
this
.
time
,
this
.
duration
,
this
.
location
);
Appointment
(
this
.
id
,
this
.
name
,
this
.
year
,
this
.
month
,
this
.
day
,
this
.
time
,
this
.
duration
,
this
.
location
,
this
.
note
);
// leeres Appointment
Appointment
.
zero
();
factory
Appointment
.
fromJson
(
Map
<
String
,
dynamic
>
appointment
)
=>
Appointment
(
_toInt
(
appointment
[
'id'
]),
appointment
[
'contactCodes'
]
as
List
<
String
>,
appointment
[
'id'
]
as
int
,
appointment
[
'name'
]
as
String
,
appointment
[
'year'
]
as
int
,
appointment
[
'month'
]
as
int
,
appointment
[
'day'
]
as
int
,
appointment
[
'time'
]
as
String
,
appointment
[
'duration'
]
as
String
,
appointment
[
'location'
]
as
String
);
appointment
[
'location'
]
as
String
,
appointment
[
'note'
]
as
String
);
List
<
String
>
contactCodes
;
List
<
String
>
contactCodes
=
[]
;
int
id
;
String
name
;
int
year
;
...
...
@@ -25,30 +25,46 @@ class Appointment {
int
day
;
String
time
=
""
;
String
duration
=
""
;
String
location
;
String
location
=
""
;
String
note
=
""
;
Map
toJson
()
=>
{
'
contactCodes'
:
contactCodes
,
Map
<
String
,
dynamic
>
toJson
()
=>
{
'
id'
:
id
,
'name'
:
name
,
'year'
:
year
,
'month'
:
month
,
"day"
:
day
,
'time'
:
time
,
'duration'
:
duration
,
'location'
:
location
'location'
:
location
,
'note'
:
note
};
///date like 'yyyy-mm-dd'
set
date
(
String
str
)
{
final
List
split
=
str
.
split
(
"-"
);
year
=
_toInt
(
split
[
0
]);
month
=
_toInt
(
split
[
1
]);
day
=
_toInt
(
split
[
2
]);
final
List
<
String
>
split
=
str
.
split
(
"-"
);
year
=
int
.
parse
(
split
[
0
]);
month
=
int
.
parse
(
split
[
1
]);
day
=
int
.
parse
(
split
[
2
]);
}
String
get
date
{
return
"
$year
-
$month
-
$day
"
;
}
}
int
_toInt
(
id
)
=>
id
is
int
?
id
:
int
.
parse
(
id
as
String
);
bool
equals
(
Appointment
app
)
{
return
id
==
app
.
id
&&
year
==
app
.
year
&&
month
==
app
.
month
&&
day
==
app
.
day
&&
name
==
app
.
name
&&
time
==
app
.
time
&&
duration
==
app
.
duration
&&
location
==
app
.
location
;
}
@override
String
toString
()
{
return
"ID:
$id
Name:
$name
Date:
$date
Time:
$time
Duration:
$duration
Location:
$location
Note:
$note
"
;
}
}
frontend/lib/src/model/person.dart
View file @
cace4417
abstract
class
Person
{
Person
(
this
.
contactCode
,
this
.
nickname
,
this
.
surname
,
this
.
name
,
this
.
email
);
Person
(
this
.
id
,
this
.
contactCode
,
this
.
username
,
this
.
surname
,
this
.
name
,
this
.
email
);
Person
.
zero
();
String
nickname
;
int
id
;
String
username
;
String
surname
;
String
name
;
String
email
;
String
contactCode
;
bool
equals
(
Person
person
)
{
return
email
==
person
.
email
&&
username
==
person
.
username
&&
name
==
person
.
name
&&
surname
==
person
.
surname
&&
contactCode
==
person
.
contactCode
&&
id
==
person
.
id
;
}
}
/// Hier ist der User
class
User
extends
Person
{
User
(
String
contactCode
,
String
nick
name
,
String
surname
,
String
name
,
String
email
,
String
password
,
String
mobileNo
)
:
password
=
password
,
mobileNo
=
mobileNo
,
super
(
contactCode
,
nick
name
,
surname
,
name
,
email
);
User
(
int
id
,
String
contactCode
,
String
user
name
,
String
surname
,
String
name
,
String
email
,
String
password
,
String
mobileNo
)
:
password
=
password
,
mobileNo
=
mobileNo
,
super
(
id
,
contactCode
,
user
name
,
surname
,
name
,
email
);
User
.
zero
()
:
super
.
zero
();
factory
User
.
fromJson
(
Map
<
String
,
dynamic
>
user
)
=>
User
(
user
[
'id'
]
as
int
,
user
[
'contactCode'
]
as
String
,
user
[
'
nick
name'
]
as
String
,
user
[
'
user
name'
]
as
String
,
user
[
'surname'
]
as
String
,
user
[
'name'
]
as
String
,
user
[
'email'
]
as
String
,
...
...
@@ -28,29 +45,14 @@ class User extends Person {
// ggf persistente Daten von einer Service Routine
final
List
<
Contact
>
_contactlist
=
List
();
int
id
;
String
password
;
String
mobileNo
;
// Adds a single contact, no duplicate by contactcode
void
addContact
(
Contact
con
)
{
if
(
_contactlist
.
any
((
ele
)
=>
ele
.
contactCode
!=
con
.
contactCode
))
{
_contactlist
.
add
(
con
);
}
}
// adds all Contacts, no duplicates by contactcode
void
addContacts
(
List
<
Contact
>
list
)
=>
list
.
forEach
(
addContact
);
// removes contact from list
void
rmvContact
(
Contact
con
)
=>
_contactlist
.
remove
(
con
);
// removes multiple Contacts
void
rmvAllContacts
(
List
<
Contact
>
list
)
=>
list
.
forEach
(
rmvContact
);
Map
toJson
()
=>
{
Map
<
String
,
dynamic
>
toJson
()
=>
{
'contactCode'
:
contactCode
,
'
nick
name'
:
nick
name
,
'
user
name'
:
user
name
,
'surname'
:
surname
,
'name'
:
name
,
'email'
:
email
,
...
...
@@ -61,27 +63,29 @@ class User extends Person {
Map
<
String
,
Contact
>
getMyContacts
()
{}
}
int
_toInt
(
id
)
=>
id
is
int
?
id
:
int
.
parse
(
id
as
String
);
/// Hier ist der Kontakt
class
Contact
extends
Person
{
Contact
(
String
nick
name
,
String
surname
,
String
name
,
String
email
,
Contact
(
int
id
,
String
user
name
,
String
surname
,
String
name
,
String
email
,
String
contactCode
,
String
note
)
:
super
(
contactCode
,
nick
name
,
surname
,
name
,
email
)
{
:
super
(
id
,
contactCode
,
user
name
,
surname
,
name
,
email
)
{
this
.
note
=
note
;
}
factory
Contact
.
fromJson
(
Map
<
String
,
String
>
contact
)
=>
Contact
(
contact
[
'nickname'
],
contact
[
'surname'
],
contact
[
'name'
],
contact
[
'email'
],
contact
[
'contactCode'
],
contact
[
'note'
]);
factory
Contact
.
fromJson
(
Map
<
String
,
dynamic
>
contact
)
=>
Contact
(
contact
[
'id'
]
as
int
,
contact
[
'username'
]
as
String
,
contact
[
'surname'
]
as
String
,
contact
[
'name'
]
as
String
,
contact
[
'email'
]
as
String
,
contact
[
'contactCode'
]
as
String
,
contact
[
'note'
]
as
String
);
String
contactCode
,
note
;
String
note
;
Map
toJson
()
=>
{
'nickname'
:
nickname
,
Map
<
String
,
dynamic
>
toJson
()
=>
{
'id'
:
id
,
'username'
:
username
,
'surname'
:
surname
,
'name'
:
name
,
'email'
:
email
,
...
...
@@ -89,9 +93,3 @@ class Contact extends Person {
'note'
:
note
};
}
List
<
Contact
>
list
=
[]
..
add
(
Contact
(
"dude"
,
"owski"
,
"mike"
,
"Mike.owski@gmail.com"
,
"PQ459"
,
"Pretty average Guy."
))
..
add
(
Contact
(
"dude"
,
"owski"
,
"mike"
,
"Mike.owski@gmail.com"
,
"PQ458"
,
"the underwhelming Guy."
));
frontend/lib/src/view/components/account_component.css
0 → 100644
View file @
cace4417
@import
url('https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css')
;
.form-control
{
margin
:
5px
;
width
:
97%
;
float
:
left
;
}
#noteplain
{
resize
:
none
;
background-color
:
#C9D1C8
;
border
:
none
;
}
#note
{
resize
:
none
;
}
#stern
{
margin
:
6px
;
font-size
:
12px
;
}
#delete
{
color
:
red
;
}
.invalid-feedback
{
margin
:
6px
;
}
label
{
width
:
100%
;
}
frontend/lib/src/view/components/account_component.dart
0 → 100644
View file @
cace4417
import
'package:angular/angular.dart'
;
import
'package:angular_forms/angular_forms.dart'
;
import
'package:angular_router/angular_router.dart'
;
import
'package:demo/src/model/person.dart'
;
import
'package:demo/src/view/routes/route_paths.dart'
;
import
'package:demo/src/view/services/person_service.dart'
;
import
'package:demo/src/view/components/login_component.dart'
;
import
'../main_component.dart'
;
@Component
(
selector:
'account'
,
templateUrl:
'account_component.html'
,
styleUrls:
[
'account_component.css'
],
directives:
[
coreDirectives
,
routerDirectives
,
formDirectives
],
)
/// Klasse zur verwaltung der Termine
class
AccountComponent
implements
OnActivate
{
AccountComponent
(
this
.
_userService
,
this
.
_location
,
this
.
_router
);
User
user
;
final
Location
_location
;
bool
deleteControl
=
false
;
final
Router
_router
;
final
UserService
_userService
;
bool
editSurname
=
false
;
bool
editName
=
false
;
bool
editEmail
=
false
;
bool
editMobileNo
=
false
;
bool
editPassword
=
false
;
bool
deleteAccount
=
false
;
String
newPassword
=
""
;
String
passwordWh
=
""
;
/// Folgender Code wird immer bei der Aktivierung der Klasse aufgerufen
@override
void
onActivate
(
_
,
RouterState
current
)
async
{
if
(!
LoginComponent
.
loggedIn
)
{
await
_router
.
navigate
(
'/login'
);
}
else
{
final
id
=
1
;
// User-ID muss noch hardcoded werden
if
(
id
!=
null
)
{
user
=
await
_userService
.
getById
(
id
);
}
}
}
/// Methode zum speichern der Änderungen, die man am User vorgenommen hat
Future
<
void
>
save
()
async
{
editSurname
=
false
;
editName
=
false
;
editEmail
=
false
;
editMobileNo
=
false
;
await
_userService
.
update
(
user
);
}
/// Methode zum Speichern des neuen Passworts
Future
<
void
>
savePassword
()
async
{
editPassword
=
false
;
user
.
password
=
newPassword
;
await
_userService
.
update
(
user
);
}
///Methode zum Löschen des Accounts
Future
<
void
>
delete
()
async
{
if
(
deleteControl
==
true
)
{
await
_userService
.
deleteUser
(
user
.
username
);
LoginComponent
.
loggedIn
=
false
;
AppComponent
.
showButtons
=
false
;
await
_router
.
navigate
(
'/login'
);
}
else
{
deleteControl
=
true
;
}
}
///Methode, die die übergeordnete Ansicht anzeigt
void
goBack
()
=>
_location
.
back
();
void
surnameEdit
()
{
editSurname
=
true
;
}
void
nameEdit
()
{
editName
=
true
;
}
void
emailEdit
()
{
editEmail
=
true
;
}
void
mobileNoEdit
()
{
editMobileNo
=
true
;
}
void
passwordEdit
()
{
editPassword
=
true
;
}
void
accountDelete
()
{
deleteAccount
=
true
;
}
}
\ No newline at end of file
frontend/lib/src/view/components/account_component.html
0 → 100644
View file @
cace4417
<h3>
Accountdetails
</h3>
<div
*ngIf=
"user != null"
>
<table
class=
"table"
>
<tr>
<th>
Username
</th>
<td>
{{user.username}}
</td>
</tr>
<tr
[hidden]=
"editSurname"
>
<th>
Surname
</th>
<td>
{{user.surname}}
</td>
<td><button
(click)=
"surnameEdit()"
class=
"btn"
>
Edit
</button></td>
</tr>
<tr
[hidden]=
"!editSurname"
id=
"editSurname"
>
<div
class=
"form-group"
>
<label
for=
"surname"
>
Surname
*
</label>
<input
type=
"text"
class=
"form-control"
id=
"surname"
required
placeholder=
"Max"
[(ngModel)]=
"user.surname"
#name
="
ngForm
"
>
</div>
<button
type=
"button"
class=
"btn btn-success"
(click)=
"save()"
>
Save
</button>
</tr>
<tr
[hidden]=
"editName"
>
<th>
Name
</th>
<td>
{{user.name}}
</td>
<td><button
(click)=
"nameEdit()"
class=
"btn"
>
Edit
</button></td>
</tr>
<tr
[hidden]=
"!editName"
id=
"editName"
>
<div
class=
"form-group"
>
<label
for=
"name"
>
Name
*
</label>
<input
type=
"text"
class=
"form-control"
id=
"name"
required
placeholder=
"Mustermann"
[(ngModel)]=
"user.name"
#name
="
ngForm
"
>
</div>
<button
type=
"button"
class=
"btn btn-success"
(click)=
"save()"
>
Save
</button>
</tr>
<tr
[hidden]=
"editEmail"
>
<th>
Email
</th>
<td>
{{user.email}}
</td>
<td><button
(click)=
"emailEdit()"
class=
"btn"
>
Edit
</button></td>
</tr>
<tr
[hidden]=
"!editEmail"
id=
"editEmail"
>
<div
class=
"form-group"
>
<label
for=
"email"
>
Email
*
</label>
<input
type=
"email"
class=
"form-control"
id=
"email"
required
placeholder=
"max@mustermann.de"
[(ngModel)]=
"user.email"
#name
="
ngForm
"
>
</div>
<button
type=
"button"
class=
"btn btn-success"
(click)=
"save()"
>
Save
</button>
</tr>
<tr
[hidden]=
"editMobileNo"
>
<th>
Mobile Number
</th>
<td>
{{user.mobileNo}}
</td>
<td><button
(click)=
"mobileNoEdit()"
class=
"btn"
>
Edit
</button></td>
</tr>
<tr
[hidden]=
"!editMobileNo"
id=
"editMobileNo"
>
<div
class=
"form-group"
>
<label
for=
"mobileNo"
>
Mobile Number
*
</label>
<input
type=
"text"
class=
"form-control"
id=
"mobileNo"
required
placeholder=
"0152 123456"
[(ngModel)]=
"user.mobileNo"
#name
="
ngForm
"
>
</div>
<button
type=
"button"
class=
"btn btn-success"
(click)=
"save()"
>
Save
</button>
</tr>
<tr
[hidden]=
"editPassword"
>
<th>
Password
</th>
<td></td>
<td><button
(click)=
"passwordEdit()"
class=
"btn"
>
Edit
</button></td>
</tr>
<tr
[hidden]=
"!editPassword"
id=
"editPassword"
>
<div
class=
"form-group"
>
<label
for=
"password"
>
Current Password
*
</label>
<input
type=
"password"
class=
"form-control"
id=
"password"
required
[(ngModel)]=
"user.password"
#name
="
ngForm
"
>
</div>
<div
class=
"form-group"
>
<label
for=
"newPassword"
>
New Password
*
</label>
<input
type=
"password"
class=
"form-control"
id=
"newPassword"
required
pattern=
"(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
[(ngModel)]=
"newPassword"
#name
="
ngForm
"
>
</div>
<div
class=
"form-group"
>
<label
for=
"passwordWh"
>
Repeat New Password
*
</label>
<input
type=
"password"
class=
"form-control"
id=
"passwordWh"
required
pattern=
"{{newPassword}}"
[(ngModel)]=
"passwordWh"
#name
="
ngForm
"
>
</div>
<button
type=
"button"
class=
"btn btn-success"
(click)=
"savePassword()"
>
Save
</button>
</tr>
<tr
[hidden]=
"deleteAccount"
>
<th>
Delete Account
</th>
<td></td>
<td><button
(click)=
"accountDelete()"
class=
"btn"
>
Edit
</button></td>
</tr>
<tr
[hidden]=
"!deleteAccount"
id=
"deleteAccount"
>
<div
class=
"form-group"
>
<label
for=
"password"
>
Password
*
</label>
<input
type=
"password"
class=
"form-control"
id=
"passwordDelete"
required
[(ngModel)]=
"user.password"
#name
="
ngForm
"
>
</div>
<div
class=
"form-group"
>
<label
for=
"passwordWh"
>
Repeat Password
*
</label>
<input
type=
"password"
class=
"form-control"
id=
"passwordWhDelete"
required
pattern=
"{{user.password}}"
[(ngModel)]=
"passwordWh"
#name
="
ngForm
"
>
</div>
<button
type=
"button"
class=
"btn btn-danger"
(click)=
"delete()"
>
Delete
</button>
<div
[hidden]=
"!deleteControl"
id=
"delete"
>
If you really want to delete your account click "Delete" again.
</div>
</tr>
</table>
<button
(click)=
"goBack()"
class=
"btn"
>
GoBack
</button>
</div>
\ No newline at end of file
frontend/lib/src/view/components/appointment_component.css
View file @
cace4417
...
...
@@ -6,10 +6,28 @@
float
:
left
;
}
#noteplain
{
resize
:
none
;