FEA: added event requests, added permission editor
This commit is contained in:
parent
6bab82fa57
commit
eed52375d6
|
@ -0,0 +1,19 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
drop table if exists event_requests;
|
||||
DELETE
|
||||
FROM permissions
|
||||
WHERE permission LIKE 'modules.event_management.requests.create' ESCAPE '#';
|
||||
DELETE
|
||||
FROM permissions
|
||||
WHERE permission LIKE 'modules.event_management.requests.edit' ESCAPE '#';
|
||||
DELETE
|
||||
FROM permissions
|
||||
WHERE permission LIKE 'modules.event_management.requests.view' ESCAPE '#';
|
||||
DELETE
|
||||
FROM permissions
|
||||
WHERE permission LIKE 'modules.event_management.requests.delete' ESCAPE '#';
|
||||
DELETE
|
||||
FROM permissions
|
||||
WHERE permission LIKE 'modules.event_management.requests.assignments.assign' ESCAPE '#';
|
||||
alter table events drop column related_request;
|
||||
alter table events drop column state;
|
|
@ -0,0 +1,53 @@
|
|||
-- Your SQL goes here
|
||||
create table event_requests
|
||||
(
|
||||
entity_id uuid not null
|
||||
constraint event_requests_pk
|
||||
primary key
|
||||
constraint event_request_entities_entity_id_fk
|
||||
references entities
|
||||
on update cascade on delete cascade,
|
||||
name text not null,
|
||||
timescale text,
|
||||
site text,
|
||||
organiser_id uuid,
|
||||
etype uuid,
|
||||
related_group uuid
|
||||
constraint event_requests_groups_entity_id_fk
|
||||
references groups,
|
||||
contact_on_site_name text,
|
||||
contact_on_site_phone text,
|
||||
specials text,
|
||||
requested text,
|
||||
expected_attendees integer,
|
||||
risk_potential integer,
|
||||
state smallint default 0 not null,
|
||||
received timestamp default now() not null
|
||||
);
|
||||
|
||||
INSERT INTO permissions (permission, description, context)
|
||||
VALUES ('modules.event_management.requests.view', 'Permission to see all event requests', false);
|
||||
INSERT INTO permissions (permission, description, context)
|
||||
VALUES ('modules.event_management.requests.edit', 'Permission to modify event requests', false);
|
||||
INSERT INTO permissions (permission, description, context)
|
||||
VALUES ('modules.event_management.requests.delete', 'Permission to delete event requests', false);
|
||||
INSERT INTO permissions (permission, description, context)
|
||||
VALUES ('modules.event_management.requests.create', 'Permission to create new event requests', false);
|
||||
INSERT INTO permissions (permission, description, context, context_type)
|
||||
VALUES ('modules.event_management.requests.assignments.assign', 'Permission to assign requests to a group', true, 'groups');
|
||||
INSERT INTO roles_permissions (role_id, permission_id, role_permission_id)
|
||||
VALUES ('admin', 'modules.event_management.requests.view', DEFAULT);
|
||||
INSERT INTO roles_permissions (role_id, permission_id, role_permission_id)
|
||||
VALUES ('admin', 'modules.event_management.requests.edit', DEFAULT);
|
||||
INSERT INTO roles_permissions (role_id, permission_id, role_permission_id)
|
||||
VALUES ('admin', 'modules.event_management.requests.delete', DEFAULT);
|
||||
INSERT INTO roles_permissions (role_id, permission_id, role_permission_id)
|
||||
VALUES ('admin', 'modules.event_management.requests.create', DEFAULT);
|
||||
INSERT INTO roles_permissions (role_id, permission_id, role_permission_id)
|
||||
VALUES ('admin', 'modules.event_management.requests.assignments.assign', DEFAULT);
|
||||
|
||||
alter table events
|
||||
add related_request uuid;
|
||||
alter table events
|
||||
add state smallint default 0 not null;
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<div class="card">
|
||||
<a href="#collapse-{{entity_id}}" style="color: black !important" data-toggle="collapse"><div class="card-header"><span class="font-weight-bold">{{received}}: </span>{{name}}</div></a>
|
||||
<div id="collapse-{{entity_id}}" class="collapse requestlist_accordion_card" data-entity-id="{{entity_id}}">
|
||||
<div class="card-body">
|
||||
<ul class="nav nav-tabs request_list_navtabs" id="evenlist_tab-{{entity_id}}" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" href="#requestlist_core_tab-{{entity_id}}" id="core-tab-{{entity_id}}" data-toggle="tab" data-bs-toggle="tab" data-bs-target="#requestlist_core_tab-{{entity_id}}" aria-controls="core-tab" aria-selected="true">Anfrage</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" href="#requestlist_state_tab-{{entity_id}}" id="state-tab-{{entity_id}}" data-toggle="tab" data-bs-toggle="tab" data-bs-target="#requestlist_state_tab-{{entity_id}}" aria-controls="state-tab" aria-selected="false">Vergabe</a>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<span style="cursor:pointer;" class="nav-link edit_request_button" data-request-id="{{entity_id}}" id="edit-tab-{{entity_id}}" aria-selected="false">Bearbeiten</span>
|
||||
</li>
|
||||
</ul><br>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active edit_event_core_data" role="tabpanel" aria-labelledby="core-tab" id="requestlist_core_tab-{{entity_id}}">
|
||||
<div class="requestlist_accordion_card_overview row">
|
||||
<div class="col-md-6">
|
||||
<h5>Anfrage</h5>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-name" class="col-sm-3 col-form-label">Name</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="{{entity_id}}-name" readonly value="{{name}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-etype" class="col-sm-3 col-form-label">Einsatzart</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" id="{{entity_id}}-etype" disabled readonly>
|
||||
{{#each etypes}}
|
||||
<option value="{{type_id}}" {{#if active}}selected{{/if}}>{{name}} {{#if is_billable}}(€){{/if}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Zeitraum</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="row m-0">
|
||||
<textarea class="form-control" rows="4" id="{{entity_id}}-timescale" readonly>{{timescale}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-site" class="col-sm-3 col-form-label">Veranstaltungsort</label>
|
||||
<div class="col-sm-9">
|
||||
<textarea rows="4" class="form-control" id="{{entity_id}}-site" readonly>{{site}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-risk_potential" class="col-sm-3 col-form-label">Risikopotential</label>
|
||||
<div class="col-sm-9">
|
||||
<select readonly disabled class="form-control" id="{{entity_id}}-risk_potential">
|
||||
<option value="1" {{#if risk_potential_low}}selected{{/if}}>geringes Risiko</option>
|
||||
<option value="2" {{#if risk_potential_medium}}selected{{/if}}>mittleres Risiko</option>
|
||||
<option value="3" {{#if risk_potential_high}}selected{{/if}}>hohes Risiko</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-expected_attendees" class="col-sm-3 col-form-label">Erwartete Besucher</label>
|
||||
<div class="col-sm-9">
|
||||
<input id="{{entity_id}}-expected_attendees" type="number" class="form-control" readonly value="{{expected_attendees}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-specials" class="col-sm-3 col-form-label">Besonderheiten (z.B. Alkoholausschank)</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="row m-0">
|
||||
<textarea class="form-control" rows="4" id="{{entity_id}}-specials" readonly>{{specials}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-requested" class="col-sm-3 col-form-label">Angeforderte Einheiten</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="row m-0">
|
||||
<textarea class="form-control" rows="4" id="{{entity_id}}-requested" readonly>{{requested}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5>Status</h5>
|
||||
<select id="{{entity_id}}-state" class="form-control" disabled readonly>
|
||||
<option value="0"></option>
|
||||
<option value="1" {{#if state_1}}selected{{/if}}>Neue Anfrage</option>
|
||||
<option value="3" {{#if state_3}}selected{{/if}}>Anfrage geprüft</option>
|
||||
<option value="5" {{#if state_5}}selected{{/if}}>Anfrage an Gruppen freigegeben</option>
|
||||
<option value="7" {{#if state_7}}selected{{else}}disabled{{/if}}>Anfrage von Gruppe übernommen</option>
|
||||
</select><br>
|
||||
<h5>Veranstalter</h5>
|
||||
{{> search base=this.osearch_base type="organiser"}}
|
||||
{{#if organiser.phone}}<p><b>Telefon: </b>{{organiser.phone}}</p>{{/if}}
|
||||
{{#if organiser.email}}<p><b>Email: </b>{{organiser.email}}</p>{{/if}}
|
||||
{{#if organiser.other}}<p><b>Sonstiges: </b>{{organiser.other}}</p>{{/if}}
|
||||
<br>
|
||||
<h5>Ansprechpartner vor Ort</h5>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-contact_on_site_name" class="col-sm-3 col-form-label">Name</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="{{entity_id}}-contact_on_site_name" readonly value="{{contact_on_site_name}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-contact_on_site_phone"
|
||||
class="col-sm-3 col-form-label">Telefonnummer</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="{{entity_id}}-contact_on_site_phone" readonly value="{{contact_on_site_phone}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" role="tabpanel" aria-labelledby="state-tab" id="requestlist_state_tab-{{entity_id}}">
|
||||
{{#if enable_assignment}}
|
||||
<div class="form-group row">
|
||||
<label for="{{entity_id}}-assignment" class="col-sm-3 col-form-label">Vergeben an:</label>
|
||||
<div class="col-sm-6">
|
||||
<div class="row m-0">
|
||||
<select class="form-control" id="{{entity_id}}-assignment">
|
||||
<option value="none">unvergeben</option>
|
||||
{{#each groups_with_assign_permission}}
|
||||
<option value="{{id}}" {{#if active}}selected{{/if}}>{{name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
Für die Vergabe an Gruppen muss der Status der Anfrage auf "Anfrage an Gruppen freigegeben" gesetzt werden!
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,16 @@
|
|||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Permission</th>
|
||||
<th scope="col">Beschreibung</th>
|
||||
<th scope="col">Kontext</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="permission_list_tbody">{{#each permissions}}<tr data-context="{{context}}" data-context-type="{{context_type}}" class=" {{#if has_permission}}{{else}} text-muted{{/if}}">
|
||||
<td><input type="checkbox" class="permission_checkbox" data-permission="{{permission}}" {{#if has_permission}}checked{{/if}}></td>
|
||||
<td class="permission_row">{{permission}}</td>
|
||||
<td class="permission_row">{{description}}</td>
|
||||
<td class="permission_row">{{context_combined}}</td>
|
||||
</tr>{{/each}}</tbody>
|
||||
</table>
|
|
@ -0,0 +1,58 @@
|
|||
{{#if groups}}
|
||||
<h3>Gruppen</h3>
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Gruppe</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="permission_context_list_tbody">{{#each groups}}
|
||||
<tr
|
||||
class=" {{#if has_this_context}}{{else}} text-muted{{/if}}">
|
||||
<td><input type="checkbox" class="permission_context_checkbox" data-context-id="{{group_id}}" {{#if has_this_context}}checked{{/if}}>
|
||||
</td>
|
||||
<td class="permission_row" title="{{description}}">{{name}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
||||
{{#if members}}
|
||||
<h3>Mitglieder</h3>
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Mitglieder</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{{#each members}}
|
||||
<tr class=" {{#if has_this_context}}{{else}} text-muted{{/if}}">
|
||||
<td><input type="checkbox" class="permission_context_checkbox" data-context-id="{{entity_id}}" {{#if has_this_context}}checked{{/if}}>
|
||||
</td>
|
||||
<td class="permission_row">{{firstname}} {{lastname}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
||||
{{#if vehicles}}
|
||||
<h3>Fahrzeuge</h3>
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Fahrzeug</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{{#each vehicles}}
|
||||
<tr class=" {{#if has_this_context}}{{else}} text-muted{{/if}}">
|
||||
<td><input type="checkbox" class="permission_context_checkbox" data-context-id="{{entity_id}}" {{#if has_this_context}}checked{{/if}}>
|
||||
</td>
|
||||
<td class="permission_row" title="{{description}}">{{identifier}} ({{numberplate}})</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
|
@ -0,0 +1,23 @@
|
|||
<table class="table table-hover table-striped">
|
||||
<thead class="thead">
|
||||
<tr>
|
||||
<th><button class="iconbutton check_all_roles"><svg width="1.25em" height="1.25em" fill="currentColor">
|
||||
<use xlink:href="/img/bootstrap-icons.svg#check-all"/>
|
||||
</svg></button></th>
|
||||
<th>Name</th>
|
||||
<th>Beschreibung</th>
|
||||
<th># Mitglieder</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each this}}
|
||||
<tr data-role-id="{{id}}" class="role-tr" style="cursor: pointer;">
|
||||
<td><input type="checkbox" class="role_entry_checkbox" data-role-id="{{id}}" data-role-name="{{name}}"></td>
|
||||
<td>{{id}}</td>
|
||||
<td>{{description}}</td>
|
||||
<td>{{member_count}}</td>
|
||||
</tr></span>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
<span><button class="iconbutton check_all_roles" data-check-all-selector=".check_all_roles"><svg width="1.25em" height="1.25em" fill="currentColor" style="margin-left: 12px;margin-right: 12px;"><use xlink:href="/img/bootstrap-icons.svg#check-all"/></svg></button><button type="button" class="btn btn-danger btn-sm roles_delete_button">Löschen</button></span>
|
|
@ -0,0 +1,7 @@
|
|||
{{#each this}}
|
||||
<tr>
|
||||
<td><input type="checkbox" class="member_checkbox" data-member-id="{{entity_id}}"></td>
|
||||
<td>{{firstname}}</td>
|
||||
<td>{{lastname}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
|
@ -6,7 +6,7 @@ $( document ).ready(function() {
|
|||
|
||||
$("#member_responsible_remove").on("click", EventCreateModule.member_responsible_remove);
|
||||
$("#organiser_remove").on("click", EventCreateModule.organiser_remove);
|
||||
load_event_types(EventCreateModule.set_event_types);
|
||||
load_event_types_legacy(EventCreateModule.set_event_types);
|
||||
load_groups(EventCreateModule.set_groups);
|
||||
$("#create_event_btn").on("click", EventCreateModule.add_event);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
$( document ).ready(function() {
|
||||
var organiser_search = new MiniSearchbar("add_event_organiser_search", RequestCreateModule.organiser_callback);
|
||||
organiser_search.setup();
|
||||
|
||||
$("#organiser_remove").on("click", RequestCreateModule.organiser_remove);
|
||||
load_event_types_legacy(RequestCreateModule.set_event_types);
|
||||
$("#create_request_btn").on("click", RequestCreateModule.add_request);
|
||||
});
|
||||
|
||||
RequestCreateModule = ( function() {
|
||||
let organiser_callback = function(caller){
|
||||
$("#create-event-organiser-search").hide();
|
||||
$("#organiser").val($(caller).data("company")+" "+$(caller).data("firstname")+" "+$(caller).data("lastname")).attr("data-entity-id", $(caller).data("entity-id"));
|
||||
$("#organiser_input_group").show();
|
||||
};
|
||||
let organiser_remove = function(){
|
||||
$("#organiser_input_group").hide();
|
||||
$("#organiser").val("").removeData("entity-id").removeAttr("data-entity-id");
|
||||
$("#add_event_organiser_search-searchbar").val("");
|
||||
$(".add_event_organiser_search-search-result-overlay-list").html("");
|
||||
$("#create-event-organiser-search").show();
|
||||
};
|
||||
let add_request = function(){
|
||||
if($("#create_request_form")[0].checkValidity()) {
|
||||
let request = {};
|
||||
request.name = $("#name").val();
|
||||
if($("#timescale").val().length > 0) {
|
||||
request.timescale = $("#timescale").val();
|
||||
}
|
||||
if($("#site").val().length > 0){
|
||||
request.site = $("#site").val();
|
||||
}
|
||||
if($("#etype").val().length > 0){
|
||||
request.etype = $("#etype option:selected").data("type-id");
|
||||
}
|
||||
if($("#organiser").data("entity-id")){
|
||||
request.organiser_id = $("#organiser").data("entity-id");
|
||||
}
|
||||
if($("#specials").val().length > 0){
|
||||
request.specials = $("#specials").val();
|
||||
}
|
||||
if($("#requested").val().length > 0){
|
||||
request.requested = $("#requested").val();
|
||||
}
|
||||
if($("#contact_on_site_name").val().length > 0){
|
||||
request.contact_on_site_name = $("#contact_on_site_name").val();
|
||||
}
|
||||
if($("#contact_on_site_phone").val().length > 0){
|
||||
request.contact_on_site_phone = $("#contact_on_site_phone").val();
|
||||
}
|
||||
if($("#expected_attendees").val().length > 0){
|
||||
request.expected_attendees = $("#expected_attendees").val();
|
||||
}
|
||||
if($("#risk_potential").val().length > 0){
|
||||
request.risk_potential = $("#risk_potential").val();
|
||||
}
|
||||
console.log(request);
|
||||
$.ajax({
|
||||
url: '/api/event_requests',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(request),
|
||||
success: function (data) {
|
||||
if (is_ok(data)) {
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
},
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Verbindung zum Server unterbrochen!");
|
||||
}
|
||||
});
|
||||
}else{
|
||||
$('<input type="submit">').hide().appendTo("#create_request_form").click().remove();
|
||||
}
|
||||
};
|
||||
let set_event_types = function(res){
|
||||
$(res).each(function(){
|
||||
let is_billable = "";
|
||||
if(this.is_billable){
|
||||
is_billable = " (€) ";
|
||||
}
|
||||
$("#etype").append("<option data-type-id=\""+this.type_id+"\">"+this.name+is_billable+"</option>");
|
||||
});
|
||||
};
|
||||
let set_groups = function(res){
|
||||
$(res.groups).each(function(){
|
||||
$("#related_group").append("<option data-group-id=\""+this.group_id+"\">"+this.name+"</option>");
|
||||
});
|
||||
}
|
||||
return{
|
||||
set_groups: set_groups,
|
||||
set_event_types: set_event_types,
|
||||
add_request: add_request,
|
||||
organiser_remove: organiser_remove,
|
||||
organiser_callback: organiser_callback,
|
||||
}
|
||||
}());
|
|
@ -268,20 +268,6 @@ EventListModule = ( function() {
|
|||
return res.name;
|
||||
}
|
||||
};
|
||||
let get_event_type = async function(type_id){
|
||||
const res = await $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/events/types/" + type_id,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Verbindung zum Server unterbrochen!");
|
||||
},
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res.name;
|
||||
}
|
||||
};
|
||||
let check_edit_permission_callback = function(has_permission){
|
||||
if(has_permission === true){
|
||||
$(".eventlist_navtabs").each(function(){
|
||||
|
|
|
@ -0,0 +1,283 @@
|
|||
limit = 5;
|
||||
|
||||
$( document ).ready(async function() {
|
||||
await RequestListModule.load_templates();
|
||||
await RequestListModule.prepare();
|
||||
RequestListModule.setup_pagination();
|
||||
RequestListModule.load_requests();
|
||||
});
|
||||
|
||||
RequestListModule = ( function() {
|
||||
let old_offset = 0;
|
||||
let templates = {};
|
||||
let event_types = {};
|
||||
let groups_with_assign_pem = [];
|
||||
let prepare = async function(){
|
||||
groups_with_assign_pem = await get_group_caller_has_asign_permissions();
|
||||
event_types = await load_event_types();
|
||||
};
|
||||
let load_templates = async function(){
|
||||
const em_request_card = $.get("/templates/em_request_card.hbs");
|
||||
const pagination = $.get("/templates/pagination.hbs");
|
||||
const search = $.get("/templates/search.hbs");
|
||||
await Promise.all([em_request_card, pagination, search]).then(function(res){
|
||||
templates.em_request_card = Handlebars.compile(res[0]);
|
||||
templates.pagination = Handlebars.compile(res[1]);
|
||||
templates.search = res[2];
|
||||
});
|
||||
Handlebars.registerPartial('search', templates.search);
|
||||
};
|
||||
let setup_pagination = function(){
|
||||
pag = new Pagination("em_eventrequests_pagination", templates.pagination, ".requestpag", limit, load_requests);
|
||||
};
|
||||
let load_requests = function(offset, args){
|
||||
if(offset === undefined || !Number.isInteger(offset)){
|
||||
offset = 0;
|
||||
}
|
||||
old_offset = offset;
|
||||
|
||||
if(args === undefined){
|
||||
args = "";
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api/event_requests?limit=" + limit + "&offset=" + offset+args,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
},
|
||||
success: async function (data) {
|
||||
if (is_ok(data)) {
|
||||
console.log(data);
|
||||
$("#requestlist_accordion").html("");
|
||||
|
||||
let loading_queue = [];
|
||||
$(data.requests).each(function(){
|
||||
loading_queue.push(load_request(this))
|
||||
});
|
||||
|
||||
async function load_request(request){
|
||||
if(request.etype){
|
||||
let types = [];
|
||||
|
||||
$(event_types).each(function(){
|
||||
let type = {};
|
||||
type.type_id = this.type_id;
|
||||
type.name = this.name;
|
||||
type.description = this.description;
|
||||
type.is_billable = this.is_billable;
|
||||
|
||||
if(type.type_id === request.etype){
|
||||
type.active = true; //mark etype for request as active
|
||||
}else{
|
||||
type.active = false;
|
||||
}
|
||||
types.push(type);
|
||||
});
|
||||
|
||||
request.etypes = types;
|
||||
}
|
||||
if(request.organiser_id){
|
||||
request.organiser = await get_organiser(request.organiser_id);
|
||||
}
|
||||
if(request.risk_potential){
|
||||
if(request.risk_potential === 1){
|
||||
request.risk_potential_low = true;
|
||||
} else if(request.risk_potential === 2){
|
||||
request.risk_potential_medium = true;
|
||||
}else if(request.risk_potential === 3){
|
||||
request.risk_potential_high = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(request.state !== 0){
|
||||
if(request.state === 1){
|
||||
request.state_1 = true;
|
||||
}
|
||||
if(request.state === 3){
|
||||
request.state_3 = true;
|
||||
}
|
||||
if(request.state === 5){
|
||||
request.enable_assignment = true;
|
||||
request.state_5 = true;
|
||||
}
|
||||
if(request.state === 7){
|
||||
request.enable_assignment = true;
|
||||
request.state_7 = true;
|
||||
}
|
||||
}
|
||||
|
||||
let date = new Date(request.received);
|
||||
request.received = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth()+1)).slice(-2) + '.' + date.getFullYear() + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
|
||||
|
||||
request.osearch_base = request.entity_id+"_organiser_search";
|
||||
|
||||
let gwap = [];
|
||||
$(groups_with_assign_pem).each(function(){
|
||||
let temp = {};
|
||||
temp.id = this.id;
|
||||
temp.name = this.name;
|
||||
temp.description = this.description;
|
||||
|
||||
if(this.id === request.related_group){
|
||||
temp.active = true;
|
||||
}else{
|
||||
temp.active = false;
|
||||
}
|
||||
gwap.push(temp);
|
||||
});
|
||||
request.groups_with_assign_permission = gwap;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
await $.when.apply($, loading_queue).then(function(){
|
||||
var objects = arguments;
|
||||
|
||||
$(objects).each(function(){
|
||||
$("#requestlist_accordion").append(templates.em_request_card(this));
|
||||
add_organiser_search(this);
|
||||
})
|
||||
})
|
||||
|
||||
$(".edit_request_button").off("click").on("click", enable_edit);
|
||||
pag.render(data.total_request_count, offset);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
let get_group_caller_has_asign_permissions = async function(){
|
||||
let res = [];
|
||||
|
||||
let groups_caller_has_assign_permissions = await get_caller_permission_context("modules.event_management.requests.assignments.assign");
|
||||
let groups = await load_groups_async();
|
||||
|
||||
$(groups).each(function(){
|
||||
let group = this;
|
||||
if(groups_caller_has_assign_permissions.indexOf(group.group_id) !== -1){
|
||||
let temp = {};
|
||||
temp.name = group.name;
|
||||
temp.description = group.description;
|
||||
temp.id = group.group_id;
|
||||
res.push(temp);
|
||||
}
|
||||
})
|
||||
|
||||
return res;
|
||||
}
|
||||
let enable_edit = function(){
|
||||
let card = $(this).closest('.card-body');
|
||||
card.find(".edit_request_button").text("Speichern").off("click").on("click", save_change);
|
||||
card.find(":input[readonly='readonly']").removeAttr("readonly").removeAttr("disabled");
|
||||
};
|
||||
let save_change = function(){
|
||||
let card = $(this).closest('.card-body');
|
||||
let entity_id = $(this).data("request-id");
|
||||
|
||||
let name = $("#"+entity_id+"-name").val();
|
||||
let etype = $("#"+entity_id+"-etype").val();
|
||||
let timescale = $("#"+entity_id+"-timescale").val();
|
||||
let site = $("#"+entity_id+"-site").val();
|
||||
let risk_potential = $("#"+entity_id+"-risk_potential").val();
|
||||
let expected_attendees = $("#"+entity_id+"-expected_attendees").val();
|
||||
let specials = $("#"+entity_id+"-specials").val();
|
||||
let requested = $("#"+entity_id+"-requested").val();
|
||||
let organiser = $("#"+entity_id+"_organiser_search").data("entity-id");
|
||||
let contact_on_site_name = $("#"+entity_id+"-contact_on_site_name").val();
|
||||
let contact_on_site_phone = $("#"+entity_id+"-contact_on_site_phone").val();
|
||||
let state = $("#"+entity_id+"-state").val();
|
||||
let assignment = $("#"+entity_id+"-assignment").val();
|
||||
|
||||
let er = {};
|
||||
er.entity_id = entity_id;
|
||||
if(name !== ""){
|
||||
er.name = name;
|
||||
}
|
||||
if(etype !== ""){
|
||||
er.etype = etype;
|
||||
}
|
||||
if(timescale !== ""){
|
||||
er.timescale = timescale;
|
||||
}
|
||||
if(site !== ""){
|
||||
er.site = site;
|
||||
}
|
||||
if(risk_potential !== ""){
|
||||
er.risk_potential = risk_potential;
|
||||
}
|
||||
if(expected_attendees !== "") {
|
||||
er.expected_attendees = expected_attendees;
|
||||
}
|
||||
if(specials !== "") {
|
||||
er.specials = specials;
|
||||
}
|
||||
if(requested !== "") {
|
||||
er.requested = requested;
|
||||
}
|
||||
if(organiser !== ""){
|
||||
er.organiser_id = organiser;
|
||||
}
|
||||
if(contact_on_site_name !== ""){
|
||||
er.contact_on_site_name = contact_on_site_name;
|
||||
}
|
||||
if(contact_on_site_phone !== ""){
|
||||
er.contact_on_site_phone = contact_on_site_phone;
|
||||
}
|
||||
if(state !== ""){
|
||||
er.state = state;
|
||||
if(state === "5" && assignment !== "" && assignment !== "none"){ //update state to request taken by group if related group is set and status is request published
|
||||
er.state = "7";
|
||||
}else{
|
||||
console.log("ass:"+assignment+"state:"+state);
|
||||
}
|
||||
}
|
||||
console.log(assignment);
|
||||
if(assignment !== "" && assignment !== "none" && assignment != null){
|
||||
er.related_group = assignment;
|
||||
}
|
||||
|
||||
console.log(er);
|
||||
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
url: "/api/event_requests/" + entity_id,
|
||||
data: JSON.stringify(er),
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
},
|
||||
success: async function (data) {
|
||||
if (is_ok(data)) {
|
||||
window.location.reload(true)
|
||||
//card.find(".edit_request_button").text("Bearbeiten").off("click").on("click", enable_edit);
|
||||
//card.find(":input").attr("readonly", true).attr("disabled", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
let add_organiser_search = function(request){
|
||||
let delete_callback = function(){
|
||||
|
||||
};
|
||||
var val = request.organiser_id;
|
||||
var val_name = null;
|
||||
if(request.organiser){
|
||||
val_name = request.organiser.company;
|
||||
if(request.organiser.firstname && request.organiser.lastname){
|
||||
val_name += ": "+request.organiser.firstname+" "+request.organiser.lastname
|
||||
}
|
||||
}
|
||||
var organiser_search = new MiniSearchbar(request.entity_id+"_organiser_search", null, val, val_name, delete_callback);
|
||||
organiser_search.setup($("#"+this.entity_id+"_organiser_search"));
|
||||
};
|
||||
return{
|
||||
load_requests: load_requests,
|
||||
load_templates: load_templates,
|
||||
setup_pagination: setup_pagination,
|
||||
prepare: prepare,
|
||||
save_change: save_change,
|
||||
}
|
||||
}());
|
|
@ -17,6 +17,21 @@ function is_ok(data){
|
|||
}
|
||||
}
|
||||
|
||||
let get_event_type = async function(type_id){
|
||||
const res = await $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/events/types/" + type_id,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Verbindung zum Server unterbrochen!");
|
||||
},
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res.name;
|
||||
}
|
||||
}
|
||||
|
||||
function check_for_permission(callback, permission, entity_id){
|
||||
let optional_entity = "";
|
||||
if(entity_id){
|
||||
|
@ -74,6 +89,21 @@ let get_member = async function (entity_id){
|
|||
}
|
||||
};
|
||||
|
||||
let get_members = async function (){
|
||||
const res = await $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/members?limit=10000&offset=0&sort=firstname:asc",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Verbindung zum Server unterbrochen!");
|
||||
},
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
let get_vehicle = async function (entity_id){
|
||||
const res = await $.ajax({
|
||||
type: "GET",
|
||||
|
@ -93,6 +123,20 @@ let get_vehicle = async function (entity_id){
|
|||
}
|
||||
}
|
||||
};
|
||||
let get_vehicles = async function (){
|
||||
const res = await $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/resources/vehicles?entries=10000",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Verbindung zum Server unterbrochen!");
|
||||
},
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let load_positions_for_instance = async function(instance_id){
|
||||
const res = await $.ajax({
|
||||
url: '/api/events/instances/'+instance_id+'/positions',
|
||||
|
@ -140,7 +184,7 @@ let remove_instance = function(){
|
|||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
let add_entity_to_position = function(instance, position, entity){
|
||||
$.ajax({
|
||||
url: '/api/events/instances/'+instance+'/positions/'+position+'/entities/'+entity,
|
||||
|
@ -188,7 +232,7 @@ let get_organiser = async function(entity_id){
|
|||
}
|
||||
};
|
||||
|
||||
let load_event_types = function(callback){
|
||||
let load_event_types_legacy = function(callback){
|
||||
$.ajax({
|
||||
url: '/api/events/types',
|
||||
type: 'GET',
|
||||
|
@ -204,6 +248,20 @@ let load_event_types = function(callback){
|
|||
}
|
||||
});
|
||||
};
|
||||
let load_event_types = async function(){
|
||||
const res = await $.ajax({
|
||||
url: '/api/events/types',
|
||||
type: 'GET',
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Verbindung zum Server unterbrochen!");
|
||||
}
|
||||
});
|
||||
if(is_ok(res)){
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let load_groups = function(callback){
|
||||
$.ajax({
|
||||
url: '/api/groups',
|
||||
|
@ -264,6 +322,21 @@ let check_position_requirements = async function(position_id, member_id){
|
|||
}
|
||||
};
|
||||
|
||||
let get_caller_permission_context = async function(permission){
|
||||
const res = await $.ajax({
|
||||
url: '/api/info/caller/permission_context?permission='+permission,
|
||||
type: 'GET',
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if(is_ok(res)){
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ajaxStart(function() {
|
||||
$(".loading_animation").show();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
active_permission = null;
|
||||
|
||||
$(document).ready(async function () {
|
||||
$("#settings_permissions_role").on("change", async function () {
|
||||
await RequestListModule.load_role();
|
||||
});
|
||||
await RequestListModule.load_templates();
|
||||
});
|
||||
|
||||
RequestListModule = (function () {
|
||||
let templates = {};
|
||||
let load_templates = async function () {
|
||||
const permission_list = $.get("/templates/settings_role_permissions.hbs");
|
||||
const context_list = $.get("/templates/settings_role_permissions_context.hbs");
|
||||
|
||||
await Promise.all([permission_list, context_list]).then(function (res) {
|
||||
templates.permission_list = Handlebars.compile(res[0]);
|
||||
templates.context_list = Handlebars.compile(res[1]);
|
||||
});
|
||||
};
|
||||
let permission_checkbox_toggle = async function () {
|
||||
let checkbox = $(this);
|
||||
if (checkbox.prop("checked")) {
|
||||
await add_permission_to_role($("#settings_permissions_role").val(), checkbox.data("permission"));
|
||||
} else {
|
||||
await remove_permission_from_role($("#settings_permissions_role").val(), checkbox.data("permission"));
|
||||
}
|
||||
};
|
||||
let permission_context_checkbox_toggle = async function () {
|
||||
console.log("removing/adding context")
|
||||
let checkbox = $(this);
|
||||
if (checkbox.prop("checked")) {
|
||||
await add_context($("#settings_permissions_role").val(), active_permission, checkbox.data("context-id"));
|
||||
} else {
|
||||
await remove_context($("#settings_permissions_role").val(), active_permission, checkbox.data("context-id"));
|
||||
}
|
||||
};
|
||||
let add_permission_to_role = async function (role, permission) {
|
||||
const res = $.ajax({
|
||||
type: "POST",
|
||||
url: "/api/roles/" + role + "/permissions/" + permission,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let remove_permission_from_role = async function (role, permission) {
|
||||
const res = $.ajax({
|
||||
type: "DELETE",
|
||||
url: "/api/roles/" + role + "/permissions/" + permission,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let add_context = async function (role, permission, context) {
|
||||
const res = $.ajax({
|
||||
type: "POST",
|
||||
url: "/api/roles/" + role + "/permissions/" + permission+"/context/"+context,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let remove_context = async function (role, permission, context) {
|
||||
const res = $.ajax({
|
||||
type: "DELETE",
|
||||
url: "/api/roles/" + role + "/permissions/" + permission+"/context/"+context,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let get_permissions = async function () {
|
||||
const res = $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/permissions/",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let combine_permissions = function (all_permissions, positive_permissions) {
|
||||
let res = [];
|
||||
|
||||
function is_in_list(permission, list) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (permission === list[i].permission) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$(all_permissions).each(function () {
|
||||
let permission = this.permission;
|
||||
|
||||
let temp = {};
|
||||
temp.permission = permission;
|
||||
temp.description = this.description;
|
||||
temp.context = this.context;
|
||||
temp.context_type = this.context_type;
|
||||
|
||||
temp.has_permission = is_in_list(permission, positive_permissions);
|
||||
|
||||
if (this.context === false) {
|
||||
temp.context_combined = "ohne";
|
||||
}
|
||||
if (this.context === true) {
|
||||
temp.context_combined = this.context_type;
|
||||
}
|
||||
|
||||
res.push(temp);
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
let load_role = async function () {
|
||||
let role = $("#settings_permissions_role").val();
|
||||
let permission_card = $(".settings_permissions_permission_card");
|
||||
|
||||
if (role !== "none") {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api/roles/" + role + "/permissions/",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
},
|
||||
success: async function (data) {
|
||||
if (is_ok(data)) {
|
||||
console.log(data);
|
||||
|
||||
let res = {};
|
||||
|
||||
let all_permissions = await get_permissions();
|
||||
res.permissions = combine_permissions(all_permissions, data);
|
||||
|
||||
console.log(res.permissions);
|
||||
|
||||
permission_card.html(templates.permission_list(res));
|
||||
$(".permission_checkbox").off("change").on("change", RequestListModule.permission_checkbox_toggle);
|
||||
$(".permission_row").off("click").on("click", load_context);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
permission_card.html("Bitte Rolle wählen.");
|
||||
}
|
||||
|
||||
};
|
||||
let load_context = async function () {
|
||||
let role = $("#settings_permissions_role").val();
|
||||
let permission = $(this).parent().find(".permission_checkbox").data("permission");
|
||||
active_permission = permission;
|
||||
|
||||
let has_context = $(this).parent().data("context");
|
||||
let context_type = $(this).parent().data("context-type");
|
||||
|
||||
if(has_context) {
|
||||
let res = {};
|
||||
|
||||
let context = await get_context(role, permission);
|
||||
if(context_type === "groups" || context_type === "members" || context_type === "entity"){
|
||||
let tempres = [];
|
||||
let groups = await load_groups_async();
|
||||
for(let i=0;i<groups.length;i++){
|
||||
|
||||
let temp = {};
|
||||
temp.group_id = groups[i].group_id;
|
||||
temp.name = groups[i].name;
|
||||
temp.description = groups[i].description;
|
||||
|
||||
temp.has_this_context = false;
|
||||
|
||||
for(let b=0;b<context.length;b++){
|
||||
if(!temp.has_this_context){
|
||||
if(groups[i].group_id === context[b]){
|
||||
temp.has_this_context = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tempres.push(temp);
|
||||
}
|
||||
res.groups = tempres;
|
||||
}
|
||||
if(context_type === "vehicles" || context_type === "entity"){
|
||||
let tempres = [];
|
||||
let vehicles = (await get_vehicles()).vehicle_list;
|
||||
for(let i=0;i<vehicles.length;i++){
|
||||
|
||||
let temp = {};
|
||||
temp.entity_id = vehicles[i].entity_id;
|
||||
temp.identifier = vehicles[i].identifier;
|
||||
temp.description = vehicles[i].description;
|
||||
temp.numberplate = vehicles[i].numberplate;
|
||||
|
||||
temp.has_this_context = false;
|
||||
|
||||
for(let b=0;b<context.length;b++){
|
||||
if(!temp.has_this_context){
|
||||
if(vehicles[i].entity_id === context[b]){
|
||||
temp.has_this_context = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tempres.push(temp);
|
||||
}
|
||||
res.vehicles = tempres;
|
||||
}
|
||||
if(context_type === "members" || context_type === "entity"){
|
||||
let tempres = [];
|
||||
let members = (await get_members()).members;
|
||||
console.log(members);
|
||||
for(let i=0;i<members.length;i++){
|
||||
|
||||
let temp = {};
|
||||
temp.entity_id = members[i].entity_id;
|
||||
temp.firstname = members[i].firstname;
|
||||
temp.lastname = members[i].lastname;
|
||||
|
||||
temp.has_this_context = false;
|
||||
|
||||
for(let b=0;b<context.length;b++){
|
||||
if(!temp.has_this_context){
|
||||
if(members[i].entity_id === context[b]){
|
||||
temp.has_this_context = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tempres.push(temp);
|
||||
}
|
||||
res.members = tempres;
|
||||
}
|
||||
|
||||
$(".settings_permissions_permission_context_card").html(templates.context_list(res));
|
||||
|
||||
$(".permission_context_checkbox").off("click").on("click", permission_context_checkbox_toggle);
|
||||
}else{
|
||||
$(".settings_permissions_permission_context_card").html("Kein Kontext");
|
||||
}
|
||||
};
|
||||
let get_context = async function(role, permission){
|
||||
const res = $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/roles/" + role + "/permissions/" + permission + "/context",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return {
|
||||
load_templates: load_templates,
|
||||
load_role: load_role,
|
||||
permission_checkbox_toggle: permission_checkbox_toggle,
|
||||
}
|
||||
}());
|
|
@ -0,0 +1,184 @@
|
|||
active_role = null;
|
||||
|
||||
$(document).ready(async function () {
|
||||
await SettingsRoleModule.load_templates();
|
||||
await SettingsRoleModule.load_role_list();
|
||||
SettingsRoleModule.prepare();
|
||||
});
|
||||
|
||||
SettingsRoleModule = (function () {
|
||||
let templates = {};
|
||||
let roles_list = [];
|
||||
let load_templates = async function () {
|
||||
const role_list = $.get("/templates/settings_roles.hbs");
|
||||
const member_row = $.get("/templates/settings_roles_member_row.hbs");
|
||||
const search = $.get("/templates/search.hbs");
|
||||
|
||||
await Promise.all([role_list, member_row, search]).then(function (res) {
|
||||
templates.role_list = Handlebars.compile(res[0]);
|
||||
templates.member_row = Handlebars.compile(res[1]);
|
||||
templates.search = res[2];
|
||||
});
|
||||
Handlebars.registerPartial('search', templates.search);
|
||||
};
|
||||
let prepare = function(){
|
||||
var member_search = new MiniSearchbar("role_member_search", add_member_to_role_listener, null, null, null);
|
||||
member_search.setup($("#role_member_search"));
|
||||
$(".role-detailed-view-remove-member-button").on("click", delete_members_listener);
|
||||
$(".role_detailed_view_submit_core_data").on("click", update_core_data_listener);
|
||||
};
|
||||
let add_member_to_role_listener = async function(res){
|
||||
let member_id = $(res).data("entity-id");
|
||||
let firstname = $(res).data("firstname");
|
||||
let lastname = $(res).data("lastname");
|
||||
|
||||
if(is_ok(await add_member_to_role(active_role, member_id))){
|
||||
await load_role_list();
|
||||
$("tr").each(function(){
|
||||
if($(this).data("role-id") === active_role){
|
||||
$(this).click();
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
let add_member_to_role = async function(role, member){
|
||||
const res = $.ajax({
|
||||
type: "POST",
|
||||
url: "/api/roles/"+role+"/members/"+member,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
let load_roles = async function(){
|
||||
const res = $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/roles",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let load_role_members = async function(role){
|
||||
const res = $.ajax({
|
||||
type: "GET",
|
||||
url: "/api/roles/"+role+"/members",
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
if (is_ok(res)) {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
let load_role_list = async function(){
|
||||
let roles = await load_roles();
|
||||
let res = [];
|
||||
|
||||
for(let i=0;i<roles.length;i++){
|
||||
let temp = {};
|
||||
temp.id = roles[i].id;
|
||||
temp.description = roles[i].description;
|
||||
temp.members = await load_role_members(roles[i].id);
|
||||
temp.member_count = temp.members.length;
|
||||
res.push(temp);
|
||||
}
|
||||
|
||||
$("#roles").html(templates.role_list(res));
|
||||
roles_list = res;
|
||||
|
||||
$(".role-tr").off("click").on("click", function(){
|
||||
let role_id = $(this).data("role-id");
|
||||
active_role = role_id;
|
||||
|
||||
let role = null;
|
||||
|
||||
for(let i=0;i<roles_list.length;i++){
|
||||
if(roles_list[i].id === role_id){
|
||||
role = roles_list[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$("#role_detailed_view_name_input").val(role.id);
|
||||
$("#role_detailed_view_name_old").val(role.id);
|
||||
$("#role_detailed_view_description_input").val(role.description);
|
||||
|
||||
$(".role_detailed_view_tbody").html(templates.member_row(role.members));
|
||||
$(".role_detailed_view").removeAttr('hidden');
|
||||
});
|
||||
};
|
||||
let delete_members_listener = async function(){
|
||||
let delete_list = [];
|
||||
$(".member_checkbox:checked").each(function(){
|
||||
delete_list.push($(this).data("member-id"));
|
||||
});
|
||||
|
||||
let promises = [];
|
||||
|
||||
$(delete_list).each(function(){
|
||||
promises.push(remove_member_from_role(active_role, this));
|
||||
});
|
||||
await Promise.all(promises).then(async function (res) {
|
||||
await load_role_list();
|
||||
$("tr").each(function(){
|
||||
if($(this).data("role-id") === active_role){
|
||||
$(this).click();
|
||||
}
|
||||
})
|
||||
});
|
||||
};
|
||||
let remove_member_from_role = async function(role, member){
|
||||
const res = $.ajax({
|
||||
type: "DELETE",
|
||||
url: "/api/roles/"+role+"/members/"+member,
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
let update_core_data_listener = async function(){
|
||||
let old_id = $("#role_detailed_view_name_old").val();
|
||||
let updated = {};
|
||||
updated.id = $("#role_detailed_view_name_input").val();
|
||||
updated.description = $("#role_detailed_view_description_input").val();
|
||||
if(is_ok(await update_core_data(old_id, updated))){
|
||||
await load_role_list();
|
||||
$("tr").each(function(){
|
||||
if($(this).data("role-id") === active_role){
|
||||
$(this).click();
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
let update_core_data = async function(old_id, role){
|
||||
const res = $.ajax({
|
||||
type: "PUT",
|
||||
url: "/api/roles/"+old_id,
|
||||
data: JSON.stringify(role),
|
||||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
error: function () {
|
||||
alert("Es ist ein Fehler aufgetreten!");
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
return {
|
||||
load_templates: load_templates,
|
||||
load_role_list: load_role_list,
|
||||
prepare: prepare,
|
||||
}
|
||||
}());
|
|
@ -0,0 +1,18 @@
|
|||
Hallo {{firstname}},
|
||||
|
||||
es wurde eine neue Einsatzanfrage in Einsatz Online eingetragen:
|
||||
|
||||
=====
|
||||
|
||||
Name: {{request.name}}
|
||||
Zeitraum: {{request.timescale}}
|
||||
Veranstaltungsraum: {{request.site}}
|
||||
Veranstalter: {{organiser.company}} ({{organiser.firstname}} {{organiser.lastname}})
|
||||
Angefordert: {{request.requested}}
|
||||
Erwartete Besucher: {{request.expected_attendees}}
|
||||
|
||||
=====
|
||||
|
||||
Möchtest du die Anfrage für deine Gruppe annehmen? Dann melde dich bei {{frontpage}} an und ordne dir diese Einsatzanfrage unter Anfragen zu.
|
||||
|
||||
Möchtest du solche E-Mails nicht mehr erhalten? Dann wende dich bitte an {{support_email}}.
|
|
@ -0,0 +1,146 @@
|
|||
{{> header }}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="wrapper">
|
||||
{{> sidebar }}
|
||||
<div id="content">
|
||||
{{> searchbar}}
|
||||
<hr>
|
||||
<h1>Einsatzanfrage anlegen</h1>
|
||||
|
||||
<div class="col">
|
||||
<form id="create_request_form">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label">Name*</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="name" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Zeitraum</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="row m-0">
|
||||
<textarea class="form-control" rows="4" id="timescale"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="site" class="col-sm-3 col-form-label">Veranstaltungsort</label>
|
||||
<div class="col-sm-9">
|
||||
<textarea rows="4" class="form-control" id="site"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<h3>Ansprechpartner vor Ort</h3>
|
||||
<div class="form-group row">
|
||||
<label for="contact_on_site_name" class="col-sm-3 col-form-label">Name</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="contact_on_site_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="contact_on_site_phone"
|
||||
class="col-sm-3 col-form-label">Telefonnummer</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="contact_on_site_phone">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group row">
|
||||
<label for="etype" class="col-sm-3 col-form-label">Einsatzart</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" id="etype">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="add_event_organiser_search-searchbar" class="col-sm-3 col-form-label">Veranstalter</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="create-event-organiser-search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control"
|
||||
id="add_event_organiser_search-searchbar"
|
||||
data-search-type="organiser">
|
||||
<span class="input-group-append">
|
||||
<span class="btn btn-outline-secondary"
|
||||
type="button">
|
||||
<svg width="16" height="16"
|
||||
fill="currentColor">
|
||||
<use xlink:href="/img/bootstrap-icons.svg#search"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="add_event_organiser_search-search-result-overlay"
|
||||
style="display: none;">
|
||||
<ul class="add_event_organiser_search-search-result-overlay-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group" id="organiser_input_group" style="display: none">
|
||||
<input type="text" disabled id="organiser" class="form-control">
|
||||
<span class="input-group-append">
|
||||
<span class="btn btn-outline-secondary"
|
||||
id="organiser_remove"
|
||||
type="button">
|
||||
<svg width="16" height="16"
|
||||
fill="currentColor">
|
||||
<use xlink:href="/img/bootstrap-icons.svg#pencil-square"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="risk_potential" class="col-sm-3 col-form-label">Risikopotential</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" id="risk_potential">
|
||||
<option value="1">geringes Risiko</option>
|
||||
<option value="2">mittleres Risiko</option>
|
||||
<option value="3">hohes Risiko</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="expected_attendees" class="col-sm-3 col-form-label">Erwartete Besucher</label>
|
||||
<div class="col-sm-9">
|
||||
<input id="expected_attendees" type="number" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="specials" class="col-sm-3 col-form-label">Besonderheiten (z.B. Alkoholausschank)</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="row m-0">
|
||||
<textarea class="form-control" rows="4" id="specials"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="requested" class="col-sm-3 col-form-label">Angeforderte Einheiten</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="row m-0">
|
||||
<textarea class="form-control" rows="4" id="requested"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p>* Pflichtfelder</p>
|
||||
<div class="col text-center">
|
||||
<button type="button" class="btn btn-success" id="create_request_btn">Anfrage
|
||||
anlegen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{> footer }}
|
|
@ -0,0 +1,29 @@
|
|||
{{> header }}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="wrapper">
|
||||
{{> sidebar }}
|
||||
<div id="content">
|
||||
{{> searchbar}}
|
||||
<hr>
|
||||
<div class="col">
|
||||
<div class="form-group row align-items-center">
|
||||
<h1 class="col-sm-4">Einsatzanfragen</h1>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">Einsatzanfragen</div>
|
||||
<div class="card-body">
|
||||
<input type="hidden" id="caller_entity_id" value="{{caller}}">
|
||||
<div id="requestlist_accordion">
|
||||
</div>
|
||||
<br>
|
||||
<div class="row requestpag">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{> footer }}
|
|
@ -12,16 +12,34 @@
|
|||
<label for="settings_permissions_role"
|
||||
class="col-auto col-form-label font-weight-bold">Rolle:</label>
|
||||
<div class="col-auto">
|
||||
<select class="form-control" id="settings_permissions_role"></select>
|
||||
<select class="form-control" id="settings_permissions_role">
|
||||
<option value="none">Rolle auswählen</option>
|
||||
{{#each roles}}
|
||||
<option title="{{description}}">{{id}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="alert alert-info" role="alert">
|
||||
Alle Änderungen werden sofort angewendet, daher gibt es keinen Speichern Button :)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<div class="card">
|
||||
<div class="card-header">Rechte für Rolle bearbeiten</div>
|
||||
<div class="card-body">Bitte Rolle wählen.</div>
|
||||
<div class="card-body settings_permissions_permission_card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<div class="card sticky-top" style="top: 15px;">
|
||||
<div class="card-header">Kontext</div>
|
||||
<div class="card-body settings_permissions_permission_context_card"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
{{> header }}
|
||||
{{> delete-roles-modal}}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="wrapper">
|
||||
{{> sidebar }}
|
||||
<div id="content">
|
||||
{{> searchbar}}
|
||||
<hr>
|
||||
{{#if alert}}
|
||||
{{> alert}}
|
||||
{{/if}}
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header">Rollen</div>
|
||||
<div class="card-body" id="roles">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header">Neue Rolle anlegen</div>
|
||||
<div class="card-body" id="new_role">
|
||||
<form>
|
||||
<div class="form-role row">
|
||||
<label for="new_role_name" class="col-sm-2 col-form-label">Name</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="new_role_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-role row">
|
||||
<label for="new_role_description" class="col-sm-2 col-form-label">Beschreibung</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="new_role_description">
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary new_role_button" style="float: right">Rolle Hinzufügen</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-light mb-3 role_detailed_view" hidden>
|
||||
<div class="card-header">Rolle <span class="role_detailed_view_name"></span></div>
|
||||
<div class="card-body" id="role_list">
|
||||
<div class="role_detailed_view_core_data">
|
||||
<div class="form-role row">
|
||||
<label for="role_detailed_view_name_input" class="col-sm-2 col-form-label">Name</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="role_detailed_view_name_input">
|
||||
<input type="hidden" id="role_detailed_view_name_old">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-role row">
|
||||
<label for="role_detailed_view_description_input" class="col-sm-2 col-form-label">Beschreibung</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" id="role_detailed_view_description_input">
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="role_detailed_view_submit_core_data btn btn-primary" style="float: right; margin-bottom:15px;">Änderungen Speichern</button>
|
||||
</div>
|
||||
<div class="role_detailed_view_member_list">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><button class="iconbutton role_detailed_view_check_all_members"><svg width="1.25em" height="1.25em" fill="currentColor">
|
||||
<use xlink:href="/img/bootstrap-icons.svg#check-all"/>
|
||||
</svg></button></th>
|
||||
<th>Vorname</th>
|
||||
<th>Nachname</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="role_detailed_view_tbody"></tbody>
|
||||
</table>
|
||||
<div>
|
||||
<button class="iconbutton role_detailed_view_check_all_members"><svg width="1.25em" height="1.25em" fill="currentColor" style="margin-left: 12px;margin-right: 12px;"><use xlink:href="/img/bootstrap-icons.svg#check-all"/></svg></button><button type="button" class="btn btn-warning btn-sm role-detailed-view-remove-member-button">Entfernen</button>
|
||||
</div><br>
|
||||
<div class="role_detailed_view_add_member">
|
||||
<div id="role-member-search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="role_member_search-searchbar" data-search-type="member">
|
||||
<span class="input-group-append">
|
||||
<span class="btn btn-outline-secondary" type="button">
|
||||
<svg width="16" height="16" fill="currentColor">
|
||||
<use xlink:href="/img/bootstrap-icons.svg#search"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="role_member_search-search-result-overlay" style="display: none;">
|
||||
<ul class="role_member_search-search-result-overlay-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{> footer }}
|
|
@ -70,6 +70,7 @@
|
|||
<li><a href="/portal/em/organisers">Veranstalter</a></li>
|
||||
<li><a href="/portal/em/eu_templates">Vorlagen</a></li>
|
||||
<li><a href="/portal/em/eu_positions">Positionen</a></li>
|
||||
<li><a href="/portal/em/requests">Anfragen</a></li>
|
||||
</ul>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
@ -81,6 +82,7 @@
|
|||
{{#if sidebar.settings.active}}
|
||||
<ul>
|
||||
<li><a href="/portal/settings/permissions">Rechtevergabe</a></li>
|
||||
<li><a href="/portal/settings/roles">Rollen</a></li>
|
||||
</ul>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
@ -97,6 +99,9 @@
|
|||
<li>
|
||||
<a href="/portal/em/add_event">Einsatz hinzufügen</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/portal/em/add_request">Anfrage hinzufügen</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
<div class="versiontag">
|
||||
|
|
|
@ -1 +1 @@
|
|||
v0.2-39-g18868d8
|
||||
v0.2-53-g6bab82f
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
use crate::helper::settings::Settings;
|
||||
use rocket::State;
|
||||
use crate::database::model::event_requests::EventRequest;
|
||||
use diesel::{RunQueryDsl, ExpressionMethods};
|
||||
use crate::database::controller::connector::establish_connection;
|
||||
use crate::diesel::QueryDsl;
|
||||
|
||||
pub fn add_event_request(settings: &State<Settings>, data: EventRequest) -> Result<EventRequest, diesel::result::Error>{
|
||||
use crate::schema::event_requests::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match diesel::insert_into(event_requests).values(data).get_result(&connection){
|
||||
Ok(er) => Ok(er),
|
||||
Err(e) => {
|
||||
error!("Couldn't create event request: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_event_request(settings: &State<Settings>, request_id: uuid::Uuid) -> Result<Option<EventRequest>, diesel::result::Error>{
|
||||
use crate::diesel::OptionalExtension;
|
||||
use crate::schema::event_requests::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match event_requests.filter(entity_id.eq(request_id)).get_result(&connection).optional(){
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {
|
||||
error!("Couldn't get event request: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_event_requests(settings: &State<Settings>, limit: i64, offset: i64, state2: Option<i16>) -> Result<Vec<EventRequest>, diesel::result::Error>{
|
||||
use crate::schema::event_requests::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
let mut query = event_requests.order(received.desc()).limit(limit).offset(offset).into_boxed();
|
||||
|
||||
match state2{
|
||||
Some(state2) => {
|
||||
query = query.filter(state.eq(state2));
|
||||
}
|
||||
None => {}
|
||||
};
|
||||
|
||||
match query.get_results(&connection){
|
||||
Ok(requestlist) => Ok(requestlist),
|
||||
Err(e) => {
|
||||
error!("Couldn't get event requests: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_event_request_count(settings: &State<Settings>, state2: Option<i16>) -> Result<i64, diesel::result::Error>{
|
||||
use crate::schema::event_requests::dsl::*;
|
||||
use diesel::dsl::count;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
let mut query = event_requests.select(count(entity_id)).into_boxed();
|
||||
|
||||
match state2{
|
||||
Some(state2) => {query = query.filter(state.eq(state2))},
|
||||
None => {}
|
||||
};
|
||||
|
||||
match query.get_result(&connection){
|
||||
Ok(requestcount) => Ok(requestcount),
|
||||
Err(e) => {
|
||||
error!("Couldn't get event request count: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_event_request(settings: &State<Settings>, data: EventRequest) -> Result<EventRequest, diesel::result::Error>{
|
||||
use crate::schema::event_requests::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match diesel::update(event_requests.filter(entity_id.eq(data.entity_id))).set(data).get_result(&connection){
|
||||
Ok(er) => Ok(er),
|
||||
Err(e) => {
|
||||
error!("Couldn't update event request: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -74,13 +74,22 @@ pub fn get_event(settings: &State<Settings>, event_id: uuid::Uuid) -> Result<Eve
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_event_count(settings: &State<Settings>, startdate: NaiveDateTime, enddate: NaiveDateTime) -> Result<i64, diesel::result::Error>{
|
||||
pub fn get_event_count(settings: &State<Settings>, startdate: NaiveDateTime, enddate: NaiveDateTime, groups: Option<Vec<uuid::Uuid>>) -> Result<i64, diesel::result::Error>{
|
||||
use crate::schema::events::dsl::*;
|
||||
use diesel::dsl::count;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match events.select(count(entity_id)).filter(start.ge(startdate)).filter(end.le(enddate)).get_result(&connection){
|
||||
let mut query = events.select(count(entity_id)).filter(start.ge(startdate)).filter(end.le(enddate)).into_boxed();
|
||||
|
||||
match groups{
|
||||
Some(groups) => {
|
||||
query = query.filter(related_group.eq(any(groups)))
|
||||
},
|
||||
None => {}
|
||||
};
|
||||
|
||||
match query.get_result(&connection){
|
||||
Ok(eventcount) => Ok(eventcount),
|
||||
Err(e) => {
|
||||
error!("Couldn't get event count: {}", e);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::database::controller::connector::establish_connection;
|
||||
use crate::database::controller::roles::{
|
||||
add_permission_context, get_role_permission_id, get_roles,
|
||||
add_permission_context, get_role_permission_id_deprecated, get_roles,
|
||||
};
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::modules::api::groups::create::GroupRolePermission;
|
||||
|
@ -17,7 +17,7 @@ pub fn add_group_role_permission(
|
|||
role_id: String,
|
||||
permission: &str,
|
||||
) -> Result<(), diesel::result::Error> {
|
||||
let role_permission_id = get_role_permission_id(settings, role_id, permission);
|
||||
let role_permission_id = get_role_permission_id_deprecated(settings, role_id, permission);
|
||||
match role_permission_id {
|
||||
Some(id) => match add_permission_context(settings, id, group_id) {
|
||||
Ok(_) => return Ok(()),
|
||||
|
|
|
@ -22,4 +22,6 @@ pub mod vehicles;
|
|||
pub mod appointments;
|
||||
pub mod entities;
|
||||
pub mod organisers;
|
||||
pub mod events;
|
||||
pub mod events;
|
||||
pub mod event_requests;
|
||||
pub mod permissions;
|
|
@ -0,0 +1,120 @@
|
|||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::database::model::permissions::Permission;
|
||||
use crate::database::controller::connector::establish_connection;
|
||||
use diesel::{ExpressionMethods, JoinOnDsl, QueryDsl, RunQueryDsl, OptionalExtension, sql_query};
|
||||
use crate::schema::members_roles::dsl::members_roles;
|
||||
use diesel::sql_types::Text;
|
||||
use diesel::pg::types::sql_types::Uuid;
|
||||
|
||||
/// Retrieves permission row for specified permission
|
||||
///
|
||||
/// # Returns:
|
||||
// /// * Ok(Some([`crate::database::model::permissions::Permission`])) if permission found
|
||||
// /// * Ok(None) if no permission found but query returned no error
|
||||
// /// * Err([`diesel::result::Error`]) if query returned error
|
||||
pub fn get_permission(settings: &State<Settings>, permission_str: &str) -> Result<Option<Permission>, diesel::result::Error>{
|
||||
use crate::schema::permissions::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match permissions.filter(permission.eq(permission_str)).get_result(&connection).optional(){
|
||||
Ok(per) => Ok(per),
|
||||
Err(e) => {
|
||||
error!("Couldn't get permission: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Retrieve role_permission_id for specified permission/role combo
|
||||
///
|
||||
/// # Returns:
|
||||
/// * Ok(Some(role_permission_id)) if role_permission_id found
|
||||
/// * Ok(None) if no role_permission_id found but query succeeded
|
||||
/// * Err([`diesel::result::Error`]) if query returned error
|
||||
///
|
||||
pub fn get_role_permission_id(settings: &State<Settings>, permission_str: &str, role: &str) -> Result<Option<uuid::Uuid>, diesel::result::Error>{
|
||||
use crate::schema::roles_permissions::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match roles_permissions.filter(permission_id.eq(permission_str)).filter(role_id.eq(role)).select(role_permission_id).get_result(&connection).optional(){
|
||||
Ok(rpi) => Ok(rpi),
|
||||
Err(e) => {
|
||||
error!("Couldn't get role permission id: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn get_role_permission_context(settings: &State<Settings>, role_permission_id: uuid::Uuid) -> Result<Vec<uuid::Uuid>, diesel::result::Error>{
|
||||
use crate::schema::roles_permissions_context::dsl::{roles_permissions_context, entity};
|
||||
use crate::schema::roles_permissions_context::dsl::role_permission_id as rpi;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match roles_permissions_context.filter( rpi.eq(role_permission_id)).select(entity).get_results(&connection){
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {
|
||||
error!("Couldn't get list of entities for role_permission_id: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(QueryableByName, PartialEq, Debug)]
|
||||
struct TempQuery {
|
||||
#[sql_type = "Uuid"]
|
||||
pub(crate) member_id: uuid::Uuid,
|
||||
}
|
||||
|
||||
pub fn get_members_with_permission(settings: &State<Settings>, permission: &str) -> Result<Vec<uuid::Uuid>, diesel::result::Error>{
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
let res : Result<Vec<TempQuery>, diesel::result::Error> = sql_query("SELECT member_id FROM members_roles WHERE role_id IN (SELECT role_id FROM roles_permissions WHERE permission_id = $1);").bind::<Text, _>(permission
|
||||
).get_results(&connection);
|
||||
|
||||
match res{
|
||||
Ok(res) => Ok(res.iter().map(|tq|tq.member_id).collect()),
|
||||
Err(e) => {
|
||||
error!("Couldn't get members with permission: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_permissions(settings: &State<Settings>) -> Result<Vec<Permission>, diesel::result::Error>{
|
||||
use crate::schema::permissions::dsl::*;
|
||||
|
||||
let connection =establish_connection(settings);
|
||||
match permissions.load(&connection){
|
||||
Ok(per) => Ok(per),
|
||||
Err(e) => {
|
||||
error!("Couldn't get permission list: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_permission_to_role(settings: &State<Settings>, permission: &str, role: &str) -> Result<uuid::Uuid, diesel::result::Error>{
|
||||
use crate::schema::roles_permissions::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
match diesel::insert_into(roles_permissions).values((&role_id.eq(role), &permission_id.eq(permission))).returning(role_permission_id).get_result(&connection) {
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {error!("Couldn't add permission to role: {}", e); Err(e)}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_permission_from_role(settings: &State<Settings>, permission: &str, role: &str) -> Result<(), diesel::result::Error>{
|
||||
use crate::schema::roles_permissions::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
match diesel::delete(roles_permissions).filter(permission_id.eq(permission)).filter(role_id.eq(role)).execute(&connection) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {error!("Couldn't remove permission from role: {}", e); Err(e)}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
use crate::database::controller::connector::establish_connection;
|
||||
use crate::database::model::roles::Role;
|
||||
use crate::diesel::query_dsl::select_dsl::SelectDsl;
|
||||
use crate::helper::settings::Settings;
|
||||
use diesel::query_dsl::filter_dsl::FilterDsl;
|
||||
use diesel::{BoolExpressionMethods, ExpressionMethods, RunQueryDsl};
|
||||
use diesel::{BoolExpressionMethods, ExpressionMethods, RunQueryDsl, QueryDsl, JoinOnDsl};
|
||||
use rocket::State;
|
||||
use crate::database::model::permissions::Permission;
|
||||
use crate::modules::api::members::get_member::MemberSearchResult;
|
||||
use crate::database::model::api_members::RawMemberSearchResult;
|
||||
|
||||
pub fn get_roles(settings: &State<Settings>) -> Result<Vec<Role>, diesel::result::Error> {
|
||||
use crate::schema::roles::dsl::*;
|
||||
|
@ -19,7 +20,32 @@ pub fn get_roles(settings: &State<Settings>) -> Result<Vec<Role>, diesel::result
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_role_permission_id(
|
||||
pub fn get_roles_for_member(settings: &State<Settings>, member: uuid::Uuid) -> Result<Vec<String>, diesel::result::Error>{
|
||||
use crate::schema::members_roles::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match members_roles.filter(member_id.eq(member)).select(role_id).get_results(&connection){
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {error!("Couldn't get roles for member: {}", e); Err(e)}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_members_for_role(settings: &State<Settings>, role: &str) -> Result<Vec<RawMemberSearchResult>, diesel::result::Error>{
|
||||
use crate::schema::members_roles::dsl::*;
|
||||
use crate::schema::members::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match members_roles.inner_join(members.on(member_id.eq(entity_id))).filter(role_id.eq(role)).select((crate::schema::members::dsl::entity_id, firstname, lastname)).get_results(&connection){
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {error!("Couldn't get members in role: {}", e); Err(e)}
|
||||
}
|
||||
}
|
||||
|
||||
/// DEPRECATED DO NOT USE, WILL BE REMOVED SOON
|
||||
/// Use [crate::database::controller:permissions::get_role_permission_id] instead!
|
||||
pub fn get_role_permission_id_deprecated(
|
||||
settings: &State<Settings>,
|
||||
role_id2: String,
|
||||
permission: &str,
|
||||
|
@ -89,6 +115,26 @@ pub fn add_permission_context(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_permission_context(
|
||||
settings: &State<Settings>,
|
||||
role_permission_id2: uuid::Uuid,
|
||||
context: uuid::Uuid,
|
||||
) -> Result<(), diesel::result::Error> {
|
||||
use crate::schema::roles_permissions_context::dsl::*;
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
let deleted = diesel::delete(roles_permissions_context)
|
||||
.filter(
|
||||
role_permission_id.eq(role_permission_id2)).filter(entity.eq(context)).execute(&connection);
|
||||
match deleted {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
error!("Couldn't delete permission context: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_member_to_role(settings: &State<Settings>, member_uuid: uuid::Uuid, role: String) -> Result<(), diesel::result::Error>{
|
||||
use crate::schema::members_roles::dsl::*;
|
||||
let connection = establish_connection(settings);
|
||||
|
@ -100,4 +146,45 @@ pub fn add_member_to_role(settings: &State<Settings>, member_uuid: uuid::Uuid, r
|
|||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_member_from_role(settings: &State<Settings>, member_uuid: uuid::Uuid, role: String) -> Result<(), diesel::result::Error>{
|
||||
use crate::schema::members_roles::dsl::*;
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match diesel::delete(members_roles).filter(member_id.eq(member_uuid)).filter(role_id.eq(role)).execute(&connection){
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
error!("Couldn't remove member from role: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_permissions_for_role(settings: &State<Settings>, role: String) -> Result<Vec<Permission>, diesel::result::Error>{
|
||||
use crate::schema::permissions::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match crate::schema::roles_permissions::dsl::roles_permissions.inner_join(permissions.on(crate::schema::roles_permissions::dsl::permission_id.eq(permission))).filter(crate::schema::roles_permissions::dsl::role_id.eq(role)).select((permission, description, context, context_type)).get_results(&connection){
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {
|
||||
error!("Couldn't get permissions for role: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_role(settings: &State<Settings>, role_id: String, role: Role) -> Result<Role, diesel::result::Error>{
|
||||
use crate::schema::roles::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match diesel::update(roles).filter(id.eq(role_id)).set(role).get_result(&connection){
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {
|
||||
error!("Couldn't update role: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
use crate::schema::event_requests;
|
||||
use diesel::sql_types::{Uuid, Text, Nullable, Integer, SmallInt, Timestamp};
|
||||
use chrono::NaiveDateTime;
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize, AsChangeset, Insertable, QueryableByName)]
|
||||
#[table_name = "event_requests"]
|
||||
#[changeset_options(treat_none_as_null = "true")]
|
||||
#[primary_key(entity_id)]
|
||||
pub struct EventRequest{
|
||||
#[sql_type = "Uuid"]
|
||||
pub(crate) entity_id: uuid::Uuid,
|
||||
#[sql_type = "Text"]
|
||||
pub(crate) name: String,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) timescale: Option<String>,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) site: Option<String>,
|
||||
#[sql_type = "Nullable<Uuid>"]
|
||||
pub(crate) organiser_id: Option<uuid::Uuid>,
|
||||
#[sql_type = "Nullable<Uuid>"]
|
||||
pub(crate) etype: Option<uuid::Uuid>,
|
||||
#[sql_type = "Nullable<Uuid>"]
|
||||
pub(crate) related_group: Option<uuid::Uuid>,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) contact_on_site_name: Option<String>,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) contact_on_site_phone: Option<String>,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) specials: Option<String>,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) requested: Option<String>,
|
||||
#[sql_type = "Nullable<Integer>"]
|
||||
pub(crate) expected_attendees: Option<i32>,
|
||||
#[sql_type = "Nullable<Integer>"]
|
||||
pub(crate) risk_potential: Option<i32>,
|
||||
#[sql_type = "SmallInt"]
|
||||
pub(crate) state: i16,
|
||||
#[sql_type = "Timestamp"]
|
||||
pub(crate) received: NaiveDateTime,
|
||||
}
|
|
@ -5,7 +5,7 @@ use crate::schema::eu_positions;
|
|||
use crate::schema::eu_templates;
|
||||
use crate::schema::eu_instances;
|
||||
use crate::schema::eu_vehicle_positions;
|
||||
use diesel::sql_types::{Uuid, Text, Nullable, Jsonb, Timestamp};
|
||||
use diesel::sql_types::{Uuid, Text, Nullable, Jsonb, Timestamp, SmallInt};
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize, AsChangeset, Insertable, QueryableByName)]
|
||||
#[table_name = "events"]
|
||||
|
@ -38,6 +38,10 @@ pub struct Event{
|
|||
pub(crate) other: Option<String>,
|
||||
#[sql_type = "Nullable<Text>"]
|
||||
pub(crate) other_intern: Option<String>,
|
||||
#[sql_type = "Nullable<Uuid>"]
|
||||
pub(crate) related_request: Option<uuid::Uuid>,
|
||||
#[sql_type = "SmallInt"]
|
||||
pub(crate) state: i16,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize, AsChangeset, Insertable)]
|
||||
|
|
|
@ -12,4 +12,6 @@ pub mod login_protection;
|
|||
pub mod vehicles;
|
||||
pub mod appointments;
|
||||
pub mod organisers;
|
||||
pub mod events;
|
||||
pub mod events;
|
||||
pub mod event_requests;
|
||||
pub mod permissions;
|
|
@ -0,0 +1,11 @@
|
|||
use crate::schema::permissions;
|
||||
|
||||
#[derive(AsChangeset, Queryable, Clone, Deserialize, Serialize, Insertable)]
|
||||
#[table_name = "permissions"]
|
||||
#[primary_key(permission)]
|
||||
pub struct Permission{
|
||||
pub permission: String,
|
||||
pub description: Option<String>,
|
||||
pub context: bool,
|
||||
pub context_type: Option<String>,
|
||||
}
|
|
@ -4,6 +4,6 @@ use crate::schema::roles;
|
|||
#[table_name = "roles"]
|
||||
#[primary_key(id)]
|
||||
pub struct Role {
|
||||
pub(crate) id: String,
|
||||
pub(crate) description: Option<String>,
|
||||
pub id: String,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -92,7 +92,15 @@ fn rocket() -> _ {
|
|||
{
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!("Couldn't register mail templates: {}", e);
|
||||
error!("Couldn't register mail template: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
match mail_templates.registry.register_template_file("new_event_request_published-de", "resources/mail_templates/new_event_request_published-de.hbs")
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!("Couldn't register mail template: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -162,6 +170,7 @@ fn rocket() -> _ {
|
|||
modules::api::appointments::read::read_appointments_for_entity,
|
||||
modules::api::appointments::delete::delete_appointment,
|
||||
modules::api::info::caller::check_caller_has_permission,
|
||||
modules::api::info::caller::get_caller_permission_context,
|
||||
modules::event_management::eventlist::eventlist,
|
||||
modules::event_management::organisers::organisers,
|
||||
modules::event_management::add_event::add_event,
|
||||
|
@ -212,6 +221,24 @@ fn rocket() -> _ {
|
|||
modules::admin_settings::permissions::settings_permissions,
|
||||
modules::api::members::get_member::api_member_list,
|
||||
modules::api::events::read::check_event_cast_status,
|
||||
modules::event_management::requests::request_list,
|
||||
modules::event_management::add_request::add_request,
|
||||
modules::api::events::requests::create::create_event_request,
|
||||
modules::api::events::requests::read::read_event_requests,
|
||||
modules::api::events::requests::update::update_event_request,
|
||||
modules::api::permissions::roles::read::get_role_permissions,
|
||||
modules::api::permissions::read::get_permissions,
|
||||
modules::api::permissions::roles::update::api_add_permission_to_role,
|
||||
modules::api::permissions::roles::update::api_remove_permission_from_role,
|
||||
modules::api::permissions::roles::read::get_context_for_permission_role,
|
||||
modules::api::permissions::roles::update::api_add_context,
|
||||
modules::api::permissions::roles::update::api_remove_context,
|
||||
modules::admin_settings::roles::settings_roles,
|
||||
modules::api::permissions::roles::read::get_all_roles,
|
||||
modules::api::permissions::roles::read::get_role_members,
|
||||
modules::api::permissions::roles::update::api_add_member_to_role,
|
||||
modules::api::permissions::roles::update::api_remove_member_from_role,
|
||||
modules::api::permissions::roles::update::api_update_role,
|
||||
],
|
||||
)
|
||||
.mount("/css", FileServer::from("resources/css"))
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
pub mod permissions;
|
||||
pub mod permissions;
|
||||
pub mod roles;
|
|
@ -6,6 +6,8 @@ use rocket::http::Status;
|
|||
use crate::helper::sitebuilder::model::sidebar::Sidebar;
|
||||
use crate::helper::sitebuilder::model::general::{Header, Stylesheet, Footer, Script};
|
||||
use rocket_dyn_templates::Template;
|
||||
use crate::database::model::roles::Role;
|
||||
use crate::database::controller::roles::get_roles;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SettingsModule {
|
||||
|
@ -13,6 +15,7 @@ pub struct SettingsModule {
|
|||
pub footer: Footer,
|
||||
pub sidebar: Sidebar,
|
||||
pub caller: uuid::Uuid,
|
||||
pub roles: Vec<Role>
|
||||
}
|
||||
|
||||
#[get("/portal/settings/permissions")]
|
||||
|
@ -45,12 +48,18 @@ pub fn settings_permissions(cookie: SessionCookie, settings: &State<Settings>) -
|
|||
};
|
||||
let mut sidebar = Sidebar::new(member.clone());
|
||||
sidebar.settings.active = true;
|
||||
|
||||
let roles = match get_roles(settings){
|
||||
Ok(roles) => roles,
|
||||
Err(e) => {error!("Couldn't get roles!");return Err(Status::InternalServerError)}
|
||||
};
|
||||
|
||||
let module = SettingsModule{
|
||||
let module = SettingsModule {
|
||||
header,
|
||||
footer,
|
||||
sidebar,
|
||||
caller: member.entity_id
|
||||
caller: member.entity_id,
|
||||
roles
|
||||
};
|
||||
|
||||
Ok(Template::render("module_settings_permissions", module))
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
|
||||
use rocket::http::Status;
|
||||
use crate::helper::sitebuilder::model::sidebar::Sidebar;
|
||||
use crate::helper::sitebuilder::model::general::{Header, Stylesheet, Footer, Script};
|
||||
use rocket_dyn_templates::Template;
|
||||
use crate::database::model::roles::Role;
|
||||
use crate::database::controller::roles::get_roles;
|
||||
use crate::modules::admin_settings::permissions::SettingsModule;
|
||||
|
||||
#[get("/portal/settings/roles")]
|
||||
pub fn settings_roles(cookie: SessionCookie, settings: &State<Settings>) -> Result<Template, Status> {
|
||||
let member = match cookie.member {
|
||||
//Unwraps member from cookie or send user to login if no member specified (user skipped member selection)
|
||||
Some(member) => member,
|
||||
None => return Err(Status::Unauthorized),
|
||||
};
|
||||
|
||||
if !member.has_permission(
|
||||
crate::permissions::modules::event_management::events::VIEW.to_string(),
|
||||
) {
|
||||
return Err(Status::Forbidden);
|
||||
}
|
||||
|
||||
let header = Header {
|
||||
html_language: "de".to_string(),
|
||||
site_title: "Rollen".to_string(),
|
||||
stylesheets: vec![Stylesheet {
|
||||
path: "/css/errms.css".to_string(),
|
||||
}],
|
||||
};
|
||||
let footer = Footer {
|
||||
scripts: vec![Script {
|
||||
path: "/js/settings_roles.js".to_string(),
|
||||
}, Script {
|
||||
path: "/js/mini_searchbar.js".to_string(),
|
||||
}],
|
||||
};
|
||||
let mut sidebar = Sidebar::new(member.clone());
|
||||
sidebar.settings.active = true;
|
||||
|
||||
let roles = match get_roles(settings){
|
||||
Ok(roles) => roles,
|
||||
Err(e) => {error!("Couldn't get roles!");return Err(Status::InternalServerError)}
|
||||
};
|
||||
|
||||
let module = SettingsModule {
|
||||
header,
|
||||
footer,
|
||||
sidebar,
|
||||
caller: member.entity_id,
|
||||
roles
|
||||
};
|
||||
|
||||
Ok(Template::render("module_settings_roles", module))
|
||||
}
|
|
@ -79,7 +79,9 @@ pub fn create_event(
|
|||
member_responsible: parse_option_uuid(ecd.member_responsible)?,
|
||||
related_group: parse_option_uuid(ecd.related_group)?,
|
||||
other: ecd.other,
|
||||
other_intern: ecd.other_intern
|
||||
other_intern: ecd.other_intern,
|
||||
related_request: None,
|
||||
state: 0
|
||||
};
|
||||
|
||||
match add_event(settings, input){
|
||||
|
|
|
@ -5,3 +5,4 @@ pub mod read;
|
|||
pub mod event_units;
|
||||
pub mod types;
|
||||
pub mod instances;
|
||||
pub mod requests;
|
|
@ -79,11 +79,11 @@ pub fn read_events(
|
|||
None => None,
|
||||
};
|
||||
|
||||
let events = match get_events(settings, start, end, limit, offset, groups){
|
||||
let events = match get_events(settings, start, end, limit, offset, groups.clone()){
|
||||
Ok(events) => events,
|
||||
Err(e) => return Err(translate_diesel(e)),
|
||||
};
|
||||
let total_event_count = match get_event_count(settings, start, end){
|
||||
let total_event_count = match get_event_count(settings, start, end, groups){
|
||||
Ok(count) => count,
|
||||
Err(e) => return Err(translate_diesel(e)),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::serde::json::Json;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::{parse_member_cookie, parse_option_uuid};
|
||||
use crate::database::model::event_requests::EventRequest;
|
||||
use crate::database::controller::entities::generate_entity;
|
||||
use diesel::sql_types::Integer;
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::database::controller::event_requests::add_event_request;
|
||||
use chrono::{NaiveDateTime, ParseError, Local};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize)]
|
||||
pub struct RequestData {
|
||||
pub(crate) entity_id: Option<String>,
|
||||
pub(crate) name: String,
|
||||
pub(crate) timescale: Option<String>,
|
||||
pub(crate) site: Option<String>,
|
||||
pub(crate) organiser_id: Option<String>,
|
||||
pub(crate) etype: Option<String>,
|
||||
pub(crate) contact_on_site_name: Option<String>,
|
||||
pub(crate) contact_on_site_phone: Option<String>,
|
||||
pub(crate) related_group: Option<String>,
|
||||
pub(crate) specials: Option<String>,
|
||||
pub(crate) requested: Option<String>,
|
||||
pub(crate) expected_attendees: Option<String>,
|
||||
pub(crate) risk_potential: Option<String>,
|
||||
pub(crate) received: Option<String>,
|
||||
pub(crate) state: Option<String>,
|
||||
}
|
||||
|
||||
#[post("/api/event_requests", format = "json", data = "<create_request_data>")]
|
||||
pub fn create_event_request(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
create_request_data: Json<RequestData>,
|
||||
) -> Result<Json<EventRequest>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
if !caller.has_permission(crate::permissions::modules::event_management::requests::CREATE.to_string()) {
|
||||
return Err(Json(
|
||||
ApiError::new(403, "Keine Berechtigung, neue Einsatzanfragen anzulegen!".to_string()).to_wrapper(),
|
||||
));
|
||||
}
|
||||
|
||||
let crd = create_request_data.into_inner();
|
||||
|
||||
let entity_id = match generate_entity(settings){
|
||||
Ok(ent) => ent,
|
||||
Err(_e) => return Err(Json(ApiError::new(500, "Konnte keine neue Entität anlegen!".to_string()).to_wrapper()))
|
||||
};
|
||||
|
||||
let risk_potential : Option<i32> = match crd.risk_potential{
|
||||
Some(rp) => match rp.parse() {
|
||||
Ok(rp) => Some(rp),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse risk potential for new request: {}", e);
|
||||
return Err(Json(ApiError::new(500, "couldn't parse risk potential".to_string()).to_wrapper()))
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let expected_attendees : Option<i32> = match crd.expected_attendees{
|
||||
Some(ea) => match ea.parse() {
|
||||
Ok(ea) => Some(ea),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse expected attendees for new request: {}", e);
|
||||
return Err(Json(ApiError::new(500, "couldn't parse expected attendees".to_string()).to_wrapper()))
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let received = match crd.received{
|
||||
Some(mut rec) => {
|
||||
rec += "T00:00";
|
||||
match NaiveDateTime::parse_from_str(&rec, "%Y-%m-%dT%H:%M") {
|
||||
Ok(rec) => rec,
|
||||
Err(e) => {
|
||||
error!("Couldn't parse start datetime: {}", e);
|
||||
return Err(Json(ApiError::new(400, "Das eingegebene Datum konnte nicht verarbeitet werden.".to_string()).to_wrapper()))
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
Local::now().naive_local()
|
||||
}
|
||||
};
|
||||
|
||||
let input = EventRequest{
|
||||
entity_id,
|
||||
name: crd.name,
|
||||
timescale: crd.timescale,
|
||||
site: crd.site,
|
||||
organiser_id: parse_option_uuid(crd.organiser_id)?,
|
||||
etype: parse_option_uuid(crd.etype)?,
|
||||
related_group: None,
|
||||
contact_on_site_name: crd.contact_on_site_name,
|
||||
contact_on_site_phone: crd.contact_on_site_phone,
|
||||
specials: crd.specials,
|
||||
requested: crd.requested,
|
||||
expected_attendees,
|
||||
risk_potential,
|
||||
state: 1,
|
||||
received,
|
||||
};
|
||||
|
||||
match add_event_request(&settings, input){
|
||||
Ok(request) => Ok(Json(request)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub mod create;
|
||||
pub mod read;
|
||||
pub mod update;
|
|
@ -0,0 +1,66 @@
|
|||
use rocket::{State, Request};
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use crate::database::model::event_requests::EventRequest;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::parse_member_cookie;
|
||||
use crate::database::controller::event_requests::{get_event_requests, get_event_request_count};
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize)]
|
||||
pub struct EventRequestList{
|
||||
pub(crate) requests: Vec<EventRequest>,
|
||||
pub(crate) total_request_count: i64,
|
||||
}
|
||||
|
||||
/// get list of all event requests
|
||||
///
|
||||
/// Arguments:
|
||||
/// * settings: [Settings] struct managed by rocket
|
||||
/// * cookie: [SessionCookie]
|
||||
/// * limit: max row count, optional
|
||||
/// * offset: skip first x rows, optional
|
||||
/// * state: representing request state:
|
||||
/// * 0: unknown
|
||||
/// * 1: new (new request from extern)
|
||||
/// * 3: validated (request has been checked)
|
||||
/// * 5: published (request published)
|
||||
/// * 7: adopted (some group admin adopted request)
|
||||
#[get("/api/event_requests?<limit>&<offset>&<state>", format = "json")]
|
||||
pub fn read_event_requests(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
limit: Option<i64>,
|
||||
offset: Option<i64>,
|
||||
state: Option<i16>,
|
||||
) -> Result<Json<EventRequestList>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::event_management::requests::VIEW.to_string()) {
|
||||
return Err(Json(ApiError::new(403, "Keine Berechtigung Einsatzanfragen abzurufen!".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
let limit = match limit{
|
||||
Some(limit) => limit,
|
||||
None => settings.api.default_pagination_limit,
|
||||
};
|
||||
let offset = match offset{
|
||||
Some(offset) => offset,
|
||||
None => 0,
|
||||
};
|
||||
|
||||
let requests = match get_event_requests(settings, limit, offset, state){
|
||||
Ok(events) => events,
|
||||
Err(e) => return Err(translate_diesel(e)),
|
||||
};
|
||||
let total_request_count = match get_event_request_count(settings, state){
|
||||
Ok(count) => count,
|
||||
Err(e) => return Err(translate_diesel(e)),
|
||||
};
|
||||
|
||||
Ok(Json(EventRequestList{
|
||||
requests,
|
||||
total_request_count
|
||||
}))
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
use crate::helper::settings::Settings;
|
||||
use rocket::State;
|
||||
use rocket::serde::json::Json;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use crate::modules::api::events::requests::create::RequestData;
|
||||
use crate::database::model::event_requests::EventRequest;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::{parse_member_cookie, parse_option_uuid, parse_uuid};
|
||||
use crate::database::controller::entities::generate_entity;
|
||||
use chrono::{NaiveDateTime, Local};
|
||||
use crate::database::controller::event_requests::{add_event_request, change_event_request, get_event_request};
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::helper::mail_templates::MailTemplates;
|
||||
use crate::helper::mail_queue::queue::{MailQueue, Mail};
|
||||
use std::sync::Arc;
|
||||
use crate::database::model::organisers::Organiser;
|
||||
use crate::database::controller::organisers::get_organiser;
|
||||
use crate::database::controller::permissions::get_members_with_permission;
|
||||
use crate::database::controller::api_communication_targets::get_member_email_addresses;
|
||||
use crate::database::controller::members::get_member_by_uuid;
|
||||
|
||||
#[put("/api/event_requests/<request_id>", format = "json", data = "<create_request_data>")]
|
||||
pub fn update_event_request(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
create_request_data: Json<RequestData>,
|
||||
request_id: String,
|
||||
mt: &State<MailTemplates>, mq: &State<Arc<MailQueue>>
|
||||
) -> Result<Json<EventRequest>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
if !caller.has_permission(crate::permissions::modules::event_management::requests::EDIT.to_string()) {
|
||||
return Err(Json(
|
||||
ApiError::new(403, "Keine Berechtigung, Einsatzanfragen zu verändern!".to_string()).to_wrapper(),
|
||||
));
|
||||
}
|
||||
|
||||
let entity_id = parse_uuid(&request_id)?;
|
||||
|
||||
let old_data = match get_event_request(settings, entity_id){
|
||||
Ok(opt) => match opt{
|
||||
Some(old) => old,
|
||||
None => return Err(Json(ApiError::new(404, "Didn't found event request with specified id".to_string()).to_wrapper()))
|
||||
},
|
||||
Err(e) => return Err(translate_diesel(e))
|
||||
};
|
||||
|
||||
let crd = create_request_data.into_inner();
|
||||
|
||||
let risk_potential : Option<i32> = match crd.risk_potential{
|
||||
Some(rp) => match rp.parse() {
|
||||
Ok(rp) => Some(rp),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse risk potential for new request: {}", e);
|
||||
return Err(Json(ApiError::new(500, "couldn't parse risk potential".to_string()).to_wrapper()))
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let expected_attendees : Option<i32> = match crd.expected_attendees{
|
||||
Some(ea) => match ea.parse() {
|
||||
Ok(ea) => Some(ea),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse expected attendees for new request: {}", e);
|
||||
return Err(Json(ApiError::new(500, "couldn't parse expected attendees".to_string()).to_wrapper()))
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let received = match crd.received{
|
||||
Some(mut rec) => {
|
||||
rec += "T00:00";
|
||||
match NaiveDateTime::parse_from_str(&rec, "%Y-%m-%dT%H:%M") {
|
||||
Ok(rec) => rec,
|
||||
Err(e) => {
|
||||
error!("Couldn't parse start datetime: {}", e);
|
||||
return Err(Json(ApiError::new(400, "Das eingegebene Datum konnte nicht verarbeitet werden.".to_string()).to_wrapper()))
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
old_data.received
|
||||
}
|
||||
};
|
||||
|
||||
let state = match crd.state{
|
||||
Some(state) => match state.parse::<i16>() {
|
||||
Ok(state) => {
|
||||
if state != 1 && state != 0 && state != 3 && state != 5 && state != 7{
|
||||
warn!("Unknown state: {}", state);
|
||||
return Err(Json(ApiError::new(400, "Unknown state number.".to_string()).to_wrapper()))
|
||||
}else{
|
||||
state
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Couldn't parse state: {}", e);
|
||||
return Err(Json(ApiError::new(400, "Couldn't parse state.".to_string()).to_wrapper()))
|
||||
}
|
||||
},
|
||||
None => 0
|
||||
};
|
||||
|
||||
let input = EventRequest{
|
||||
entity_id,
|
||||
name: crd.name,
|
||||
timescale: crd.timescale,
|
||||
site: crd.site,
|
||||
organiser_id: parse_option_uuid(crd.organiser_id)?,
|
||||
etype: parse_option_uuid(crd.etype)?,
|
||||
related_group: parse_option_uuid(crd.related_group)?,
|
||||
contact_on_site_name: crd.contact_on_site_name,
|
||||
contact_on_site_phone: crd.contact_on_site_phone,
|
||||
specials: crd.specials,
|
||||
requested: crd.requested,
|
||||
expected_attendees,
|
||||
risk_potential,
|
||||
state,
|
||||
received,
|
||||
};
|
||||
|
||||
match change_event_request(&settings, input){
|
||||
Ok(request) => {
|
||||
if state == 5 && old_data.state != 5{
|
||||
debug!("State 5 is new, sending emails!");
|
||||
send_event_request_published_emails(mt, mq, settings, request.clone())
|
||||
}else{
|
||||
debug!("State is: {}, old state was: {}", state, old_data.state);
|
||||
}
|
||||
Ok(Json(request))
|
||||
},
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct NewEventRequestPublishedEmail{
|
||||
firstname: String,
|
||||
request: EventRequest,
|
||||
frontpage: String,
|
||||
support_email: String,
|
||||
organiser: Option<Organiser>
|
||||
}
|
||||
|
||||
fn send_event_request_published_emails(mt: &State<MailTemplates>, mq: &State<Arc<MailQueue>>, settings: &State<Settings>, request: EventRequest) {
|
||||
let receivers = match get_members_with_permission(settings, crate::permissions::modules::event_management::requests::assignments::ASSIGN){
|
||||
Ok(rec) => rec,
|
||||
Err(e) => {
|
||||
error!("Couldn't get email receiver list: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let organiser = match request.clone().organiser_id{
|
||||
Some(organiser) => {
|
||||
match get_organiser(settings, organiser){
|
||||
Ok(organiser) => Some(organiser),
|
||||
Err(e) => {
|
||||
error!("Couldn't get organiser for new event request to send email: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None
|
||||
};
|
||||
|
||||
for receiver in receivers{
|
||||
let emails = match get_member_email_addresses(settings, receiver){
|
||||
Ok(emails) => emails,
|
||||
Err(e) => {
|
||||
error!("Couldn't get email addresses for member: {}", e);
|
||||
continue
|
||||
}
|
||||
};
|
||||
let member = match get_member_by_uuid(receiver, settings){
|
||||
Some(member) => member,
|
||||
None => {
|
||||
error!("No member found for id {}", receiver);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let nerpe = NewEventRequestPublishedEmail{
|
||||
firstname: member.firstname,
|
||||
request: request.clone(),
|
||||
frontpage: settings.application.url.clone(),
|
||||
support_email: settings.application.user_support_email.clone(),
|
||||
organiser: organiser.clone()
|
||||
};
|
||||
let body = match mt.registry.render("new_event_request_published-de", &nerpe){
|
||||
Ok(body) => body,
|
||||
Err(e) => {
|
||||
error!("Couldn't render email template: {}", e);
|
||||
return},
|
||||
};
|
||||
|
||||
let mail = Mail::new(settings.mail.from.clone(), emails, format!("[{}] - Neue Einsatzanfrage", settings.application.name.clone()), vec![], vec![], Some(settings.mail.reply_to.clone()), body, None); //TODO: Add deliver_until
|
||||
match mq.add_mail(mail){
|
||||
Ok(_) => {},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -55,7 +55,9 @@ pub fn update_event(
|
|||
member_responsible: parse_option_uuid(ecd.member_responsible)?,
|
||||
related_group: parse_option_uuid(ecd.related_group)?,
|
||||
other: ecd.other,
|
||||
other_intern: ecd.other_intern
|
||||
other_intern: ecd.other_intern,
|
||||
related_request: None,
|
||||
state: 0
|
||||
};
|
||||
|
||||
match change_event(settings, input){
|
||||
|
|
|
@ -2,10 +2,13 @@ use rocket::State;
|
|||
use crate::helper::settings::Settings;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::serde::json::Json;
|
||||
use crate::modules::api::model::api_outcome::ApiErrorWrapper;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::{parse_member_cookie, parse_uuid_string};
|
||||
|
||||
use crate::database::controller::members::check_access_to_resource;
|
||||
use crate::database::controller::permissions::{get_permission, get_role_permission_id, get_role_permission_context};
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::database::controller::roles::get_roles_for_member;
|
||||
|
||||
/// Check if caller has permission
|
||||
///
|
||||
|
@ -36,4 +39,52 @@ pub fn check_caller_has_permission(
|
|||
Ok(Json(caller.has_permission(permission)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get context entries caller has permissions for
|
||||
///
|
||||
/// # Api Call
|
||||
/// * GET
|
||||
/// * /api/info/caller/permission_context?permission=<permission_string : String>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<Vec<uuid::Uuid>> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * None
|
||||
#[get("/api/info/caller/permission_context?<permission>", format = "json")]
|
||||
pub fn get_caller_permission_context(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
permission: String,
|
||||
) -> Result<Json<Vec<uuid::Uuid>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
let roles = match get_roles_for_member(settings, caller.entity_id){
|
||||
Ok(roles) => roles,
|
||||
Err(e) => return Err(translate_diesel(e))
|
||||
};
|
||||
|
||||
let mut res : Vec<uuid::Uuid> = vec![];
|
||||
|
||||
for role in roles{
|
||||
let rpi = get_role_permission_id(settings, &permission, &role);
|
||||
match rpi{
|
||||
Ok(rpi) => match rpi{
|
||||
Some(rpi) => {
|
||||
match get_role_permission_context(settings, rpi){
|
||||
Ok(context) => {
|
||||
res.append(&mut context.clone())
|
||||
},
|
||||
Err(e) => return Err(translate_diesel(e))
|
||||
}},
|
||||
None => {},
|
||||
},
|
||||
Err(e) => {
|
||||
return Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Json(res))
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ pub mod resources;
|
|||
pub mod appointments;
|
||||
pub mod info;
|
||||
pub mod event_organisers;
|
||||
pub mod events;
|
||||
pub mod events;
|
||||
pub mod permissions;
|
|
@ -0,0 +1,2 @@
|
|||
pub mod roles;
|
||||
pub mod read;
|
|
@ -0,0 +1,37 @@
|
|||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::serde::json::Json;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::parse_member_cookie;
|
||||
use crate::database::controller::roles::get_permissions_for_role;
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::database::model::permissions::Permission;
|
||||
|
||||
/// Get all permissions
|
||||
///
|
||||
/// # Api Call
|
||||
/// * GET
|
||||
/// * /api/permissions/
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<Vec<[Permission]>> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.view
|
||||
#[get("/api/permissions", format = "json")]
|
||||
pub fn get_permissions(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
) -> Result<Json<Vec<Permission>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::VIEW.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to read permission list".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match crate::database::controller::permissions::get_permissions(settings) {
|
||||
Ok(res) => Ok(Json(res)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod read;
|
||||
pub mod update;
|
|
@ -0,0 +1,147 @@
|
|||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::serde::json::Json;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::parse_member_cookie;
|
||||
use crate::database::controller::roles::{get_permissions_for_role, get_roles, get_members_for_role};
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::database::model::permissions::Permission;
|
||||
use crate::database::controller::permissions::{get_role_permission_id, get_role_permission_context};
|
||||
use crate::database::model::roles::Role;
|
||||
use crate::modules::api::members::get_member::MemberSearchResult;
|
||||
use crate::database::model::api_members::RawMemberSearchResult;
|
||||
|
||||
/// Get all permissions for role
|
||||
///
|
||||
/// # Api Call
|
||||
/// * GET
|
||||
/// * /api/roles/<role_id>/permissions
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<Vec<[Permission]>> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.view
|
||||
#[get("/api/roles/<role_id>/permissions", format = "json")]
|
||||
pub fn get_role_permissions(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
) -> Result<Json<Vec<Permission>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::VIEW.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to read role permissions".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match get_permissions_for_role(settings, role_id) {
|
||||
Ok(res) => Ok(Json(res)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get context for permission role
|
||||
///
|
||||
/// # Api Call
|
||||
/// * GET
|
||||
/// * /api/roles/<role_id>/permissions/<permission>/context
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<Vec<[uuid::Uuid]>> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.view
|
||||
#[get("/api/roles/<role_id>/permissions/<permission>/context", format = "json")]
|
||||
pub fn get_context_for_permission_role(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
permission: String,
|
||||
role_id: String,
|
||||
) -> Result<Json<Vec<uuid::Uuid>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::VIEW.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to read role permissions".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
let mut res : Vec<uuid::Uuid> = vec![];
|
||||
|
||||
let rpi = get_role_permission_id(settings, &permission, &role_id);
|
||||
match rpi{
|
||||
Ok(rpi) => match rpi{
|
||||
Some(rpi) => {
|
||||
match get_role_permission_context(settings, rpi){
|
||||
Ok(context) => {
|
||||
res.append(&mut context.clone())
|
||||
},
|
||||
Err(e) => return Err(translate_diesel(e))
|
||||
}},
|
||||
None => {},
|
||||
},
|
||||
Err(e) => {
|
||||
return Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Json(res))
|
||||
}
|
||||
|
||||
|
||||
/// Get all roles
|
||||
///
|
||||
/// # Api Call
|
||||
/// * GET
|
||||
/// * /api/roles/
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<Vec<[Role]>> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.view
|
||||
#[get("/api/roles", format = "json")]
|
||||
pub fn get_all_roles(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
) -> Result<Json<Vec<Role>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::VIEW.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to read roles".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match get_roles(settings) {
|
||||
Ok(res) => Ok(Json(res)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all role members
|
||||
///
|
||||
/// # Api Call
|
||||
/// * GET
|
||||
/// * /api/roles/<role_id>/members
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<Vec<[RawMemberSearchResult]>> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.view
|
||||
#[get("/api/roles/<role_id>/members", format = "json")]
|
||||
pub fn get_role_members(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
) -> Result<Json<Vec<RawMemberSearchResult>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::VIEW.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to read roles".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match get_members_for_role(settings, &role_id) {
|
||||
Ok(res) => Ok(Json(res)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::serde::json::Json;
|
||||
use crate::modules::api::model::api_outcome::{ApiErrorWrapper, ApiError};
|
||||
use crate::modules::api::member_management::controller::parser::{parse_member_cookie, parse_uuid};
|
||||
use crate::database::controller::roles::{get_permissions_for_role, add_permission_context, remove_permission_context, add_member_to_role, remove_member_from_role, update_role};
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::database::model::permissions::Permission;
|
||||
use crate::database::controller::permissions::{add_permission_to_role, remove_permission_from_role, get_role_permission_id};
|
||||
use crate::database::model::roles::Role;
|
||||
|
||||
/// Add permission to role
|
||||
///
|
||||
/// Returns new role_permission_id
|
||||
///
|
||||
/// # Api Call
|
||||
/// * POST
|
||||
/// * /api/roles/<role_id>/permissions/<permission_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<uuid::Uuid> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[post("/api/roles/<role_id>/permissions/<permission_id>", format = "json")]
|
||||
pub fn api_add_permission_to_role(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
permission_id: String,
|
||||
) -> Result<Json<uuid::Uuid>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit role permissions".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match add_permission_to_role(settings, &permission_id, &role_id) {
|
||||
Ok(res) => Ok(Json(res)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Remove permission to role
|
||||
///
|
||||
/// Returns nothing
|
||||
///
|
||||
/// # Api Call
|
||||
/// * DELETE
|
||||
/// * /api/roles/<role_id>/permissions/<permission_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<()> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[delete("/api/roles/<role_id>/permissions/<permission_id>", format = "json")]
|
||||
pub fn api_remove_permission_from_role(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
permission_id: String,
|
||||
) -> Result<Json<()>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit role permissions".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match remove_permission_from_role(settings, &permission_id, &role_id) {
|
||||
Ok(()) => Ok(Json(())),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Add context to role & permission
|
||||
///
|
||||
/// Returns nothing
|
||||
///
|
||||
/// # Api Call
|
||||
/// * POST
|
||||
/// * /api/roles/<role_id>/permissions/<permission_id>/context/<context_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<()> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[post("/api/roles/<role_id>/permissions/<permission_id>/context/<context_id>", format = "json")]
|
||||
pub fn api_add_context(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
permission_id: String,
|
||||
context_id: String,
|
||||
) -> Result<Json<()>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit role permissions".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
let rpi = match get_role_permission_id(settings, &permission_id, &role_id){
|
||||
Ok(rpi) => match rpi{
|
||||
Some(rpi) => rpi,
|
||||
None => {
|
||||
warn!("Couldn't find role_permission_id");
|
||||
return Err(Json(ApiError::new(404, "role_permission_id not found.".to_string()).to_wrapper()))
|
||||
}
|
||||
},
|
||||
Err(e) => return Err(Json(ApiError::new(500, "Couldn't get role_permission_id.".to_string()).to_wrapper())),
|
||||
};
|
||||
|
||||
let context_id = parse_uuid(&context_id)?;
|
||||
|
||||
match add_permission_context(settings, rpi, context_id){
|
||||
Ok(()) => Ok(Json(())),
|
||||
Err(e) => {Err(translate_diesel(e))}
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes context from role & permission combo
|
||||
///
|
||||
/// Returns nothing
|
||||
///
|
||||
/// # Api Call
|
||||
/// * POST
|
||||
/// * /api/roles/<role_id>/permissions/<permission_id>/context/<context_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<()> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[delete("/api/roles/<role_id>/permissions/<permission_id>/context/<context_id>", format = "json")]
|
||||
pub fn api_remove_context(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
permission_id: String,
|
||||
context_id: String,
|
||||
) -> Result<Json<()>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit role permissions".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
let rpi = match get_role_permission_id(settings, &permission_id, &role_id){
|
||||
Ok(rpi) => match rpi{
|
||||
Some(rpi) => rpi,
|
||||
None => return Err(Json(ApiError::new(404, "role_permission_id not found.".to_string()).to_wrapper()))
|
||||
},
|
||||
Err(e) => return Err(Json(ApiError::new(500, "Couldn't get role_permission_id.".to_string()).to_wrapper())),
|
||||
};
|
||||
|
||||
let context_id = parse_uuid(&context_id)?;
|
||||
|
||||
match remove_permission_context(settings, rpi, context_id){
|
||||
Ok(()) => Ok(Json(())),
|
||||
Err(e) => {Err(translate_diesel(e))}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add member to role
|
||||
///
|
||||
/// Returns nothing
|
||||
///
|
||||
/// # Api Call
|
||||
/// * POST
|
||||
/// * /api/roles/<role_id>/members/<member_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<()> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[post("/api/roles/<role_id>/members/<member_id>", format = "json")]
|
||||
pub fn api_add_member_to_role(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
member_id: String,
|
||||
) -> Result<Json<()>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit roles".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
let member_id = parse_uuid(&member_id)?;
|
||||
|
||||
match add_member_to_role(settings, member_id, role_id) {
|
||||
Ok(()) => Ok(Json(())),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes member from role
|
||||
///
|
||||
/// Returns nothing
|
||||
///
|
||||
/// # Api Call
|
||||
/// * DELETE
|
||||
/// * /api/roles/<role_id>/members/<member_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<()> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[delete("/api/roles/<role_id>/members/<member_id>", format = "json")]
|
||||
pub fn api_remove_member_from_role(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
member_id: String,
|
||||
) -> Result<Json<()>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit roles".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
let member_id = parse_uuid(&member_id)?;
|
||||
|
||||
match remove_member_from_role(settings, member_id, role_id) {
|
||||
Ok(()) => Ok(Json(())),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates role data
|
||||
///
|
||||
/// Returns Role
|
||||
///
|
||||
/// # Api Call
|
||||
/// * PUT
|
||||
/// * /api/roles/<role_id>
|
||||
///
|
||||
/// # Api Result
|
||||
/// * Result JSON<[Role]> / ApiErrorWrapper
|
||||
///
|
||||
/// # Required permissions
|
||||
/// * modules.settings.role_permissions.edit
|
||||
#[put("/api/roles/<role_id>", format = "json", data = "<role_data>")]
|
||||
pub fn api_update_role(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
role_id: String,
|
||||
role_data: Json<Role>,
|
||||
) -> Result<Json<Role>, Json<ApiErrorWrapper>> {
|
||||
let role_data = role_data.into_inner();
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
if !caller.has_permission(crate::permissions::modules::settings::role_permissions::EDIT.to_string()){
|
||||
return Err(Json(ApiError::new(403, "No permission to edit roles".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match update_role(settings, role_id, role_data) {
|
||||
Ok(res) => Ok(Json(res)),
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ use crate::modules::api::member_management::controller::parser::{parse_member_co
|
|||
use crate::database::controller::entities::generate_entity;
|
||||
use crate::database::controller::vehicles::add_vehicle;
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::database::controller::roles::{add_permission_context, get_role_permission_id};
|
||||
use crate::database::controller::roles::{add_permission_context, get_role_permission_id_deprecated};
|
||||
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize)]
|
||||
|
@ -61,19 +61,19 @@ pub fn create_vehicle(
|
|||
|
||||
match add_vehicle(settings, vehicle){
|
||||
Ok(vehicle) => {
|
||||
let rpi = match get_role_permission_id(settings, "admin".to_string(), crate::permissions::modules::resource_management::vehicles::core::EDIT){
|
||||
let rpi = match get_role_permission_id_deprecated(settings, "admin".to_string(), crate::permissions::modules::resource_management::vehicles::core::EDIT){
|
||||
Some(rpi) => rpi,
|
||||
None => return Err(Json(ApiError::new(500, "Couldn't add permission".to_string()).to_wrapper()))
|
||||
};
|
||||
let rpi2 = match get_role_permission_id(settings, "admin".to_string(), crate::permissions::modules::scheduler::appointments::VIEW){
|
||||
let rpi2 = match get_role_permission_id_deprecated(settings, "admin".to_string(), crate::permissions::modules::scheduler::appointments::VIEW){
|
||||
Some(rpi) => rpi,
|
||||
None => return Err(Json(ApiError::new(500, "Couldn't add permission".to_string()).to_wrapper()))
|
||||
};
|
||||
let rpi3 = match get_role_permission_id(settings, "admin".to_string(), crate::permissions::modules::scheduler::appointments::EDIT){
|
||||
let rpi3 = match get_role_permission_id_deprecated(settings, "admin".to_string(), crate::permissions::modules::scheduler::appointments::EDIT){
|
||||
Some(rpi) => rpi,
|
||||
None => return Err(Json(ApiError::new(500, "Couldn't add permission".to_string()).to_wrapper()))
|
||||
};
|
||||
let rpi4 = match get_role_permission_id(settings, "admin".to_string(), crate::permissions::modules::resource_management::vehicles::core::DELETE){
|
||||
let rpi4 = match get_role_permission_id_deprecated(settings, "admin".to_string(), crate::permissions::modules::resource_management::vehicles::core::DELETE){
|
||||
Some(rpi) => rpi,
|
||||
None => return Err(Json(ApiError::new(500, "Couldn't add permission".to_string()).to_wrapper()))
|
||||
};
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use rocket::http::Status;
|
||||
use crate::helper::sitebuilder::model::general::{Header, Stylesheet, Footer, Script};
|
||||
use crate::helper::sitebuilder::model::sidebar::Sidebar;
|
||||
use crate::modules::event_management::eventlist::EventTemplates;
|
||||
use rocket_dyn_templates::Template;
|
||||
|
||||
#[get("/portal/em/add_request")]
|
||||
pub fn add_request(cookie: SessionCookie, _settings: &State<Settings>) -> Result<Template, Status> {
|
||||
let member = match cookie.member {
|
||||
//Unwraps member from cookie or send user to login if no member specified (user skipped member selection)
|
||||
Some(member) => member,
|
||||
None => return Err(Status::Unauthorized),
|
||||
};
|
||||
|
||||
if !member.has_permission(
|
||||
crate::permissions::modules::event_management::requests::CREATE.to_string(),
|
||||
) {
|
||||
return Err(Status::Forbidden);
|
||||
}
|
||||
|
||||
let header = Header {
|
||||
html_language: "de".to_string(),
|
||||
site_title: "Einsatzanfrage erstellen".to_string(),
|
||||
stylesheets: vec![Stylesheet {
|
||||
path: "/css/errms.css".to_string(),
|
||||
}],
|
||||
};
|
||||
let footer = Footer {
|
||||
scripts: vec![
|
||||
Script {
|
||||
path: "/js/mini_searchbar.js".to_string(),
|
||||
},
|
||||
Script {
|
||||
path: "/js/em_create_request.js".to_string(),
|
||||
}],
|
||||
};
|
||||
let mut sidebar = Sidebar::new(member.clone());
|
||||
sidebar.event_management.active = true;
|
||||
|
||||
let eventlist = EventTemplates {
|
||||
header,
|
||||
footer,
|
||||
sidebar,
|
||||
caller: member.entity_id,
|
||||
};
|
||||
|
||||
Ok(Template::render("module_em_create_request", eventlist))
|
||||
}
|
|
@ -4,4 +4,6 @@ pub mod add_event;
|
|||
pub mod event_unit_positions;
|
||||
pub mod event_unit_templates;
|
||||
pub mod edit_event;
|
||||
pub mod check_position_requirements;
|
||||
pub mod check_position_requirements;
|
||||
pub mod requests;
|
||||
pub mod add_request;
|
|
@ -0,0 +1,59 @@
|
|||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use rocket::State;
|
||||
use crate::helper::settings::Settings;
|
||||
use rocket_dyn_templates::Template;
|
||||
use rocket::http::Status;
|
||||
use crate::helper::sitebuilder::model::general::{Header, Stylesheet, Footer, Script};
|
||||
use crate::helper::sitebuilder::model::sidebar::Sidebar;
|
||||
use crate::database::controller::groups::get_raw_groups;
|
||||
use crate::modules::event_management::eventlist::EventList;
|
||||
|
||||
#[get("/portal/em/requests")]
|
||||
pub fn request_list(cookie: SessionCookie, settings: &State<Settings>) -> Result<Template, Status> {
|
||||
let member = match cookie.member {
|
||||
//Unwraps member from cookie or send user to login if no member specified (user skipped member selection)
|
||||
Some(member) => member,
|
||||
None => return Err(Status::Unauthorized),
|
||||
};
|
||||
|
||||
if !member.has_permission(
|
||||
crate::permissions::modules::event_management::events::VIEW.to_string(),
|
||||
) {
|
||||
return Err(Status::Forbidden);
|
||||
}
|
||||
|
||||
let header = Header {
|
||||
html_language: "de".to_string(),
|
||||
site_title: "Einsatzanfragen".to_string(),
|
||||
stylesheets: vec![Stylesheet {
|
||||
path: "/css/errms.css".to_string(),
|
||||
}],
|
||||
};
|
||||
let footer = Footer {
|
||||
scripts: vec![Script {
|
||||
path: "/js/em_eventrequests.js".to_string(),
|
||||
}, Script {
|
||||
path: "/js/mini_searchbar.js".to_string(),
|
||||
},Script {
|
||||
path: "/js/pagination.js".to_string(),
|
||||
}],
|
||||
|
||||
};
|
||||
let mut sidebar = Sidebar::new(member.clone());
|
||||
sidebar.event_management.active = true;
|
||||
|
||||
let groups = match get_raw_groups(settings){
|
||||
Ok(groups) => groups,
|
||||
Err(e) => return Err(Status::InternalServerError)
|
||||
};
|
||||
|
||||
let eventlist = EventList {
|
||||
header,
|
||||
footer,
|
||||
sidebar,
|
||||
caller: member.entity_id,
|
||||
groups
|
||||
};
|
||||
|
||||
Ok(Template::render("module_em_requests", eventlist))
|
||||
}
|
|
@ -86,6 +86,16 @@ pub mod modules {
|
|||
pub const CREATE: &'static str = "modules.event_management.events.create";
|
||||
pub const DELETE: &'static str = "modules.event_management.events.delete";
|
||||
}
|
||||
pub mod requests{
|
||||
pub mod assignments{
|
||||
pub const ASSIGN: &'static str = "modules.event_management.requests.assignments.assign";
|
||||
pub const RESET: &'static str = "modules.event_management.requests.assignments.reset"; //TODO: add to database
|
||||
}
|
||||
pub const VIEW: &'static str = "modules.event_management.requests.view";
|
||||
pub const EDIT: &'static str = "modules.event_management.requests.edit";
|
||||
pub const CREATE: &'static str = "modules.event_management.requests.create";
|
||||
pub const DELETE: &'static str = "modules.event_management.requests.delete";
|
||||
}
|
||||
}
|
||||
pub mod resource_management{
|
||||
pub const VIEW: &'static str = "modules.resource_management.view";
|
||||
|
|
|
@ -194,6 +194,29 @@ table! {
|
|||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
use diesel::sql_types::*;
|
||||
use diesel_geometry::sql_types::*;
|
||||
|
||||
event_requests (entity_id) {
|
||||
entity_id -> Uuid,
|
||||
name -> Text,
|
||||
timescale -> Nullable<Text>,
|
||||
site -> Nullable<Text>,
|
||||
organiser_id -> Nullable<Uuid>,
|
||||
etype -> Nullable<Uuid>,
|
||||
related_group -> Nullable<Uuid>,
|
||||
contact_on_site_name -> Nullable<Text>,
|
||||
contact_on_site_phone -> Nullable<Text>,
|
||||
specials -> Nullable<Text>,
|
||||
requested -> Nullable<Text>,
|
||||
expected_attendees -> Nullable<Int4>,
|
||||
risk_potential -> Nullable<Int4>,
|
||||
state -> Int2,
|
||||
received -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
use diesel::sql_types::*;
|
||||
use diesel_geometry::sql_types::*;
|
||||
|
@ -224,6 +247,8 @@ table! {
|
|||
related_group -> Nullable<Uuid>,
|
||||
other -> Nullable<Text>,
|
||||
other_intern -> Nullable<Text>,
|
||||
related_request -> Nullable<Uuid>,
|
||||
state -> Int2,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,6 +350,16 @@ table! {
|
|||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
use diesel::sql_types::*;
|
||||
use diesel_geometry::sql_types::*;
|
||||
|
||||
notification_types (name) {
|
||||
name -> Text,
|
||||
description -> Nullable<Text>,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
use diesel::sql_types::*;
|
||||
use diesel_geometry::sql_types::*;
|
||||
|
@ -487,6 +522,8 @@ joinable!(eu_vehicle_positions -> entities (entity_id));
|
|||
joinable!(eu_vehicle_positions -> eu_templates (template_id));
|
||||
joinable!(eu_vehicle_positions -> vehicle_categories (required_vehicle_category));
|
||||
joinable!(event_organisers -> entities (entity_id));
|
||||
joinable!(event_requests -> entities (entity_id));
|
||||
joinable!(event_requests -> groups (related_group));
|
||||
joinable!(events -> event_organisers (organiser_id));
|
||||
joinable!(events -> event_types (etype));
|
||||
joinable!(events -> groups (related_group));
|
||||
|
@ -532,6 +569,7 @@ allow_tables_to_appear_in_same_query!(
|
|||
eu_templates,
|
||||
eu_vehicle_positions,
|
||||
event_organisers,
|
||||
event_requests,
|
||||
event_types,
|
||||
events,
|
||||
groups,
|
||||
|
@ -542,6 +580,7 @@ allow_tables_to_appear_in_same_query!(
|
|||
login_attempts_usernames,
|
||||
members,
|
||||
members_roles,
|
||||
notification_types,
|
||||
password_resets,
|
||||
permissions,
|
||||
qualification_categories,
|
||||
|
|
Loading…
Reference in New Issue