Add SelfServeConditions and SelfServeConditionRules modules with dynamic filtering and CRUD support
- Introduced `SelfServeConditions` and `SelfServeConditionRules` modules for managing conditions and rules. - Added routing, components, and backend integration for CRUD operations. - Implemented dynamic filtering based on `department_id`, `lane_id`, and `vehicle_type`. - Enhanced self-serve workflows with condition and rule management for questions and tasks. - Updated related navigation, tables, and pagination components for seamless integration.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
<script setup>
|
||||
import { usePaginatedListInstance } from "@/components/pagination/paginatedList.vue";
|
||||
const { loadList, setList } = usePaginatedListInstance();
|
||||
import EditableTableColumn from "@/components/displays/buttons/EditableTableColumn.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
|
||||
// Define the props
|
||||
const props = defineProps({
|
||||
objects: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="table is-fullwidth is-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>{{ SessionUser.objects.self_serve_condition_rules.columns.condition_id.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_condition_rules.columns.type.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_condition_rules.columns.object_type.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_condition_rules.columns.object_id.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_condition_rules.columns.name.label }}</th>
|
||||
<th class="has-text-right">{{ SessionUser.objects.global.language.actions }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="object in objects" :key="object.id">
|
||||
<td>{{ object.id }}</td>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="condition_id"
|
||||
:edit-function="SessionUser.objects.self_serve_condition_rules.showEditObjectFieldForm"
|
||||
:parse-function="SessionUser.objects.self_serve_condition_rules.columns.condition_id.parse"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="type"
|
||||
:edit-function="SessionUser.objects.self_serve_condition_rules.showEditObjectFieldForm"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="object_type"
|
||||
:edit-function="SessionUser.objects.self_serve_condition_rules.showEditObjectFieldForm"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="object_id"
|
||||
:edit-function="SessionUser.objects.self_serve_condition_rules.showEditObjectFieldForm"
|
||||
:parse-function="(id) => object.object_type === 'question' ? SessionUser.objects.self_serve_questions.functions.getQuestionText(id) : id"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="name"
|
||||
:edit-function="SessionUser.objects.self_serve_condition_rules.showEditObjectFieldForm"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<!-- Actions -->
|
||||
<td class="has-text-right">
|
||||
<button class="button is-small is-danger is-light" @click="SessionUser.objects.self_serve_condition_rules.functions.showDeleteObjectForm(object.id, loadList)">
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-trash"></i>
|
||||
</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,82 @@
|
||||
<script setup>
|
||||
import { usePaginatedListInstance } from "@/components/pagination/paginatedList.vue";
|
||||
const { loadList, setList } = usePaginatedListInstance();
|
||||
import EditableTableColumn from "@/components/displays/buttons/EditableTableColumn.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
|
||||
// Define the props
|
||||
const props = defineProps({
|
||||
objects: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="table is-fullwidth is-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>{{ SessionUser.objects.self_serve_conditions.columns.name.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_conditions.columns.description.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_conditions.columns.lane.label }}</th>
|
||||
<th>{{ SessionUser.objects.self_serve_conditions.columns.product.label }}</th>
|
||||
<th class="has-text-right">{{ SessionUser.objects.global.language.actions }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="object in objects" :key="object.id">
|
||||
<td>{{ object.id }}</td>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="name"
|
||||
:edit-function="SessionUser.objects.self_serve_conditions.showEditObjectFieldForm"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="description"
|
||||
:edit-function="SessionUser.objects.self_serve_conditions.showEditObjectFieldForm"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="lane"
|
||||
:edit-function="SessionUser.objects.self_serve_conditions.showEditObjectFieldForm"
|
||||
:parse-function="(laneId) => 'Bane ' + laneId"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<EditableTableColumn
|
||||
:object="object"
|
||||
:loadList="loadList"
|
||||
column="product"
|
||||
:edit-function="SessionUser.objects.self_serve_conditions.showEditObjectFieldForm"
|
||||
:parse-function="(productId) => SessionUser.objects.products.functions.getProductName(productId)"
|
||||
:permission-check-function="SessionUser.canAccessAdmin"
|
||||
/>
|
||||
<!-- Actions -->
|
||||
<td class="has-text-right">
|
||||
<router-link :to="{ name: 'selfserveconditionrules', params: { departmentId: SessionUser.functions.getDepartmentIdFromUrl() }, query: { condition_id: object.id } }" class="button is-small is-link is-light mr-2">
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-gavel"></i>
|
||||
</span>
|
||||
<span>Regler</span>
|
||||
</router-link>
|
||||
<button class="button is-small is-danger is-light" @click="SessionUser.objects.self_serve_conditions.functions.showDeleteObjectForm(object.id, loadList)">
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-trash"></i>
|
||||
</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<script setup>
|
||||
import SelfServeConditionRulesTable from "@/components/displays/department/tables/SelfServeConditionRulesTable.vue";
|
||||
|
||||
const props = defineProps({
|
||||
setConditionFilter: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
autoLoad: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
import { defineProps } from "vue";
|
||||
import {
|
||||
usePaginatedList,
|
||||
PaginatedListKey
|
||||
} from "@/components/pagination/paginatedList.vue";
|
||||
import { provide, computed } from "vue";
|
||||
const paginatedList = usePaginatedList();
|
||||
provide(PaginatedListKey, paginatedList);
|
||||
const {
|
||||
list,
|
||||
loadList,
|
||||
metaTotalItems,
|
||||
setEndpoint,
|
||||
setFilter,
|
||||
} = paginatedList;
|
||||
|
||||
const sortedList = computed(() => {
|
||||
return [...list.value];
|
||||
});
|
||||
|
||||
import TableLabeledPagination from "@/components/displays/pagination/TableLabeledPagination.vue";
|
||||
import {SessionUser} from "@/components/session/token/SessionUser.vue";
|
||||
|
||||
setEndpoint(SessionUser.objects.self_serve_condition_rules.meta.endpoint, false);
|
||||
|
||||
if (props.setConditionFilter) {
|
||||
setFilter(
|
||||
"condition_id",
|
||||
props.setConditionFilter
|
||||
);
|
||||
}
|
||||
|
||||
if (props.autoLoad) {
|
||||
loadList();
|
||||
}
|
||||
|
||||
import { watch } from "vue";
|
||||
watch(() => props.setConditionFilter, (newFilter) => {
|
||||
if (newFilter) {
|
||||
setFilter("condition_id", newFilter);
|
||||
} else {
|
||||
setFilter("condition_id", "*");
|
||||
}
|
||||
loadList();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
loadList
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TableLabeledPagination :label="SessionUser.objects.self_serve_condition_rules.meta.title">
|
||||
<template #buttons="{ loadList }">
|
||||
<slot name="buttons" :loadList="loadList" :totalItems="metaTotalItems">
|
||||
<button
|
||||
class="button is-primary is-small"
|
||||
@click="SessionUser.objects.self_serve_condition_rules.showCreateObjectForm({
|
||||
condition_id: props.setConditionFilter
|
||||
}, loadList)"
|
||||
>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-plus"></i>
|
||||
</span>
|
||||
<span>Tilføj {{ SessionUser.objects.self_serve_condition_rules.meta.labels.single }}</span>
|
||||
</button>
|
||||
</slot>
|
||||
</template>
|
||||
<SelfServeConditionRulesTable :objects="sortedList" />
|
||||
</TableLabeledPagination>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
<script setup>
|
||||
import SelfServeConditionsTable from "@/components/displays/department/tables/SelfServeConditionsTable.vue";
|
||||
|
||||
const props = defineProps({
|
||||
setDepartmentFilter: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
setVehicleTypeFilter: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
autoLoad: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
import { defineProps } from "vue";
|
||||
import {
|
||||
usePaginatedList,
|
||||
PaginatedListKey
|
||||
} from "@/components/pagination/paginatedList.vue";
|
||||
import { provide, computed } from "vue";
|
||||
const paginatedList = usePaginatedList();
|
||||
provide(PaginatedListKey, paginatedList);
|
||||
const {
|
||||
list,
|
||||
loadList,
|
||||
metaTotalItems,
|
||||
setEndpoint,
|
||||
setFilter,
|
||||
setOrder,
|
||||
} = paginatedList;
|
||||
|
||||
const sortedList = computed(() => {
|
||||
return [...list.value];
|
||||
});
|
||||
|
||||
import TableLabeledPagination from "@/components/displays/pagination/TableLabeledPagination.vue";
|
||||
import {SessionUser} from "@/components/session/token/SessionUser.vue";
|
||||
|
||||
setEndpoint(SessionUser.objects.self_serve_conditions.meta.endpoint, false);
|
||||
|
||||
if (props.setDepartmentFilter) {
|
||||
setFilter(
|
||||
"department",
|
||||
props.setDepartmentFilter
|
||||
);
|
||||
}
|
||||
|
||||
if (props.setVehicleTypeFilter) {
|
||||
setFilter(
|
||||
"product",
|
||||
props.setVehicleTypeFilter
|
||||
);
|
||||
}
|
||||
|
||||
if (props.autoLoad) {
|
||||
loadList();
|
||||
}
|
||||
|
||||
import { watch } from "vue";
|
||||
watch(() => props.setVehicleTypeFilter, (newFilter) => {
|
||||
if (newFilter) {
|
||||
setFilter("product", newFilter);
|
||||
} else {
|
||||
setFilter("product", "*");
|
||||
}
|
||||
loadList();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
loadList
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TableLabeledPagination :label="SessionUser.objects.self_serve_conditions.meta.title">
|
||||
<template #buttons="{ loadList }">
|
||||
<slot name="buttons" :loadList="loadList" :totalItems="metaTotalItems">
|
||||
<button
|
||||
class="button is-primary is-small"
|
||||
@click="SessionUser.objects.self_serve_conditions.showCreateObjectForm({
|
||||
department: props.setDepartmentFilter,
|
||||
product: props.setVehicleTypeFilter
|
||||
}, loadList)"
|
||||
>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-plus"></i>
|
||||
</span>
|
||||
<span>Tilføj {{ SessionUser.objects.self_serve_conditions.meta.labels.single }}</span>
|
||||
</button>
|
||||
</slot>
|
||||
</template>
|
||||
<SelfServeConditionsTable :objects="sortedList" />
|
||||
</TableLabeledPagination>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -41,6 +41,8 @@ import {OrderBookings} from "@/components/session/token/SessionUser/Objects/Orde
|
||||
import {ModuleActionLogs} from "@/components/session/token/SessionUser/Objects/ModuleActionLogs.vue";
|
||||
import {SelfServeQuestions} from "@/components/session/token/SessionUser/Objects/SelfServeQuestions.vue";
|
||||
import {SelfServeTasks} from "@/components/session/token/SessionUser/Objects/SelfServeTasks.vue";
|
||||
import {SelfServeConditions} from "@/components/session/token/SessionUser/Objects/SelfServeConditions.vue";
|
||||
import {SelfServeConditionRules} from "@/components/session/token/SessionUser/Objects/SelfServeConditionRules.vue";
|
||||
import {ObjectsGlobal} from "@/components/session/token/SessionUser/Objects/ObjectsGlobal.vue";
|
||||
import Swal from "sweetalert2";
|
||||
import router from "@/router.js";
|
||||
@@ -311,6 +313,8 @@ export const SessionUser = {
|
||||
module_action_logs: ModuleActionLogs,
|
||||
self_serve_questions: SelfServeQuestions,
|
||||
self_serve_tasks: SelfServeTasks,
|
||||
self_serve_conditions: SelfServeConditions,
|
||||
self_serve_condition_rules: SelfServeConditionRules,
|
||||
global: ObjectsGlobal,
|
||||
},
|
||||
/** The user's token and authentication status */
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
<script>
|
||||
import { ObjectsGlobal } from "@/components/session/token/SessionUser/Objects/ObjectsGlobal.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import {ref} from "vue";
|
||||
|
||||
/**
|
||||
* Local condition rules cache
|
||||
* @type {ref<null>}
|
||||
*/
|
||||
export const condition_rules_cache = ref(null);
|
||||
|
||||
/**
|
||||
* Get the condition rule name
|
||||
* @param id
|
||||
* @param fallback
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getConditionRuleName = (id, fallback = null) => {
|
||||
if (condition_rules_cache.value === null) {
|
||||
condition_rules_cache.value = [];
|
||||
SessionUser.objects.self_serve_condition_rules.get.all().then((rules) => {
|
||||
condition_rules_cache.value = rules;
|
||||
});
|
||||
}
|
||||
const rule = condition_rules_cache.value.find((rule) => rule.id === parseInt(id));
|
||||
return rule ? rule.name : fallback === null ? SessionUser.objects.global.language.no_data : fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SelfServeConditionRules object
|
||||
*/
|
||||
export const SelfServeConditionRules = {
|
||||
meta: {
|
||||
title: "Betingelsesregler",
|
||||
icon: "fas fa-gavel",
|
||||
description: "Oversigt over betingelsesregler",
|
||||
endpoint: "/department/selfserve/condition/rules",
|
||||
labels: {
|
||||
single: "regel",
|
||||
multiple: "regler"
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
label: "ID",
|
||||
type: "number",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: false
|
||||
}
|
||||
},
|
||||
condition_id: {
|
||||
label: "Betingelse",
|
||||
type: "select",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
},
|
||||
options: async (lockedValues = {}) => {
|
||||
return await SessionUser.objects.self_serve_conditions.get.all();
|
||||
},
|
||||
parse: (id) => {
|
||||
return SessionUser.objects.self_serve_conditions.functions.getConditionName(id);
|
||||
}
|
||||
},
|
||||
type: {
|
||||
label: "Type",
|
||||
type: "select",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
},
|
||||
options: async () => {
|
||||
return [
|
||||
{ id: "IS_TRUE", name: "Er sand" },
|
||||
{ id: "IS_FALSE", name: "Er falsk" },
|
||||
];
|
||||
}
|
||||
},
|
||||
object_type: {
|
||||
label: "Objekt type",
|
||||
type: "select",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
},
|
||||
options: async () => {
|
||||
return [
|
||||
{ id: "question", name: "Spørgsmål" },
|
||||
{ id: "task", name: "Opgave" },
|
||||
];
|
||||
}
|
||||
},
|
||||
object_id: {
|
||||
label: "Objekt ID",
|
||||
type: "select",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
},
|
||||
options: async (lockedValues = {}) => {
|
||||
if (lockedValues.object_type === 'question') {
|
||||
const questions = await SessionUser.objects.self_serve_questions.get.all();
|
||||
return questions.map(q => ({ id: q.id, name: q.question }));
|
||||
} else if (lockedValues.object_type === 'task') {
|
||||
const tasks = await SessionUser.objects.self_serve_tasks.get.all();
|
||||
return tasks.map(t => ({ id: t.id, name: t.task }));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
},
|
||||
name: {
|
||||
label: "Navn",
|
||||
type: "string",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
description: {
|
||||
label: "Beskrivelse",
|
||||
type: "string",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
},
|
||||
add: async (condition_id, type, object_type, object_id, name, description) => {
|
||||
return ObjectsGlobal.add.object(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
{
|
||||
condition_id: parseInt(condition_id),
|
||||
type: type,
|
||||
object_type: object_type,
|
||||
object_id: parseInt(object_id),
|
||||
name: name,
|
||||
description: description,
|
||||
}
|
||||
);
|
||||
},
|
||||
set: {
|
||||
condition_id: async (id, condition_id) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
id,
|
||||
"condition_id",
|
||||
parseInt(condition_id)
|
||||
)
|
||||
},
|
||||
type: async (id, type) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
id,
|
||||
"type",
|
||||
type
|
||||
)
|
||||
},
|
||||
object_type: async (id, object_type) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
id,
|
||||
"object_type",
|
||||
object_type
|
||||
)
|
||||
},
|
||||
object_id: async (id, object_id) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
id,
|
||||
"object_id",
|
||||
parseInt(object_id)
|
||||
)
|
||||
},
|
||||
name: async (id, name) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
id,
|
||||
"name",
|
||||
name
|
||||
)
|
||||
},
|
||||
description: async (id, description) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditionRules.meta.endpoint,
|
||||
id,
|
||||
"description",
|
||||
description
|
||||
)
|
||||
},
|
||||
},
|
||||
get: {
|
||||
all: async () => {
|
||||
return ObjectsGlobal.get.objects(SelfServeConditionRules.meta.endpoint);
|
||||
},
|
||||
single: async (id) => {
|
||||
return ObjectsGlobal.get.object(SelfServeConditionRules.meta.endpoint, id);
|
||||
}
|
||||
},
|
||||
delete: async (id) => {
|
||||
return ObjectsGlobal.delete.object(SelfServeConditionRules.meta.endpoint, id);
|
||||
},
|
||||
functions: {
|
||||
getConditionRuleName: getConditionRuleName,
|
||||
showDeleteObjectForm: (id, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showDeleteObjectForm(SelfServeConditionRules, id, onAfterSubmit);
|
||||
},
|
||||
},
|
||||
showCreateObjectForm: (initialData = {}, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showCreateObjectForm(SelfServeConditionRules, onAfterSubmit, initialData);
|
||||
},
|
||||
showEditObjectFieldForm: (id, column, value, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showEditObjectFieldForm(
|
||||
SelfServeConditionRules,
|
||||
id,
|
||||
column,
|
||||
value,
|
||||
onAfterSubmit
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,184 @@
|
||||
<script>
|
||||
import { ObjectsGlobal } from "@/components/session/token/SessionUser/Objects/ObjectsGlobal.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import {ref} from "vue";
|
||||
|
||||
/**
|
||||
* Local conditions cache
|
||||
* @type {ref<null>}
|
||||
*/
|
||||
export const conditions_cache = ref(null);
|
||||
|
||||
/**
|
||||
* Get the condition name
|
||||
* @param id
|
||||
* @param fallback
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getConditionName = (id, fallback = null) => {
|
||||
if (conditions_cache.value === null) {
|
||||
conditions_cache.value = [];
|
||||
SessionUser.objects.self_serve_conditions.get.all().then((conditions) => {
|
||||
conditions_cache.value = conditions;
|
||||
});
|
||||
}
|
||||
const condition = conditions_cache.value.find((condition) => condition.id === parseInt(id));
|
||||
return condition ? condition.name : fallback === null ? SessionUser.objects.global.language.no_data : fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SelfServeConditions object
|
||||
*/
|
||||
export const SelfServeConditions = {
|
||||
meta: {
|
||||
title: "Selvbetjeningsbetingelser",
|
||||
icon: "fas fa-filter",
|
||||
description: "Oversigt over selvbetjeningsbetingelser",
|
||||
endpoint: "/department/selfserve/conditions",
|
||||
labels: {
|
||||
single: "betingelse",
|
||||
multiple: "betingelser"
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
label: "ID",
|
||||
type: "number",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: false
|
||||
}
|
||||
},
|
||||
department: {
|
||||
label: "Afdeling",
|
||||
type: "number",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
lane: {
|
||||
label: "Bane",
|
||||
type: "number",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
product: {
|
||||
label: "Køretøjstype",
|
||||
type: "select",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
},
|
||||
options: async (lockedValues = {}) => {
|
||||
const products = await SessionUser.objects.products.get.all();
|
||||
if (lockedValues && (lockedValues.vehicle_type || lockedValues.product)) {
|
||||
return products.filter(p => parseInt(p.id) === parseInt(lockedValues.vehicle_type || lockedValues.product));
|
||||
}
|
||||
return products;
|
||||
}
|
||||
},
|
||||
name: {
|
||||
label: "Navn",
|
||||
type: "string",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
description: {
|
||||
label: "Beskrivelse",
|
||||
type: "string",
|
||||
sortable: true,
|
||||
creation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
},
|
||||
add: async (department, lane, product, name, description) => {
|
||||
return ObjectsGlobal.add.object(
|
||||
SelfServeConditions.meta.endpoint,
|
||||
{
|
||||
department: parseInt(department),
|
||||
lane: parseInt(lane),
|
||||
product: parseInt(product),
|
||||
name: name,
|
||||
description: description,
|
||||
}
|
||||
);
|
||||
},
|
||||
set: {
|
||||
name: async (id, name) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditions.meta.endpoint,
|
||||
id,
|
||||
"name",
|
||||
name
|
||||
)
|
||||
},
|
||||
description: async (id, description) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditions.meta.endpoint,
|
||||
id,
|
||||
"description",
|
||||
description
|
||||
)
|
||||
},
|
||||
product: async (id, product) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditions.meta.endpoint,
|
||||
id,
|
||||
"product",
|
||||
parseInt(product)
|
||||
)
|
||||
},
|
||||
lane: async (id, lane) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditions.meta.endpoint,
|
||||
id,
|
||||
"lane",
|
||||
parseInt(lane)
|
||||
)
|
||||
},
|
||||
department: async (id, department) => {
|
||||
return ObjectsGlobal.set.column(
|
||||
SelfServeConditions.meta.endpoint,
|
||||
id,
|
||||
"department",
|
||||
parseInt(department)
|
||||
)
|
||||
},
|
||||
},
|
||||
get: {
|
||||
all: async () => {
|
||||
return ObjectsGlobal.get.objects(SelfServeConditions.meta.endpoint);
|
||||
},
|
||||
single: async (id) => {
|
||||
return ObjectsGlobal.get.object(SelfServeConditions.meta.endpoint, id);
|
||||
}
|
||||
},
|
||||
delete: async (id) => {
|
||||
return ObjectsGlobal.delete.object(SelfServeConditions.meta.endpoint, id);
|
||||
},
|
||||
functions: {
|
||||
getConditionName: getConditionName,
|
||||
showDeleteObjectForm: (id, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showDeleteObjectForm(SelfServeConditions, id, onAfterSubmit);
|
||||
},
|
||||
},
|
||||
showCreateObjectForm: (initialData = {}, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showCreateObjectForm(SelfServeConditions, onAfterSubmit, initialData);
|
||||
},
|
||||
showEditObjectFieldForm: (id, column, value, onAfterSubmit = null) => {
|
||||
return ObjectsGlobal.showEditObjectFieldForm(
|
||||
SelfServeConditions,
|
||||
id,
|
||||
column,
|
||||
value,
|
||||
onAfterSubmit
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -104,20 +104,21 @@ export const SelfServeQuestions = {
|
||||
required: true
|
||||
},
|
||||
options: async (lockedValues = {}) => {
|
||||
let questions = await SessionUser.objects.self_serve_questions.get.all();
|
||||
let conditions = await SessionUser.objects.self_serve_conditions.get.all();
|
||||
const departmentId = lockedValues.department || lockedValues.department_id;
|
||||
const productId = lockedValues.product || lockedValues.vehicle_type || lockedValues.product_id;
|
||||
|
||||
if (departmentId) {
|
||||
questions = questions.filter(q => parseInt(q.department) === parseInt(departmentId));
|
||||
}
|
||||
if (productId) {
|
||||
questions = questions.filter(q => parseInt(q.product) === parseInt(productId));
|
||||
conditions = conditions.filter(c => parseInt(c.department) === parseInt(departmentId));
|
||||
}
|
||||
|
||||
let options = questions.map(q => ({
|
||||
...q,
|
||||
name: q.question
|
||||
if (productId) {
|
||||
conditions = conditions.filter(c => parseInt(c.product) === parseInt(productId));
|
||||
}
|
||||
|
||||
let options = conditions.map(c => ({
|
||||
...c,
|
||||
name: c.name
|
||||
}));
|
||||
|
||||
options.unshift({
|
||||
@@ -128,7 +129,7 @@ export const SelfServeQuestions = {
|
||||
return options;
|
||||
},
|
||||
parse: (id) => {
|
||||
return SessionUser.objects.self_serve_questions.functions.getQuestionText(id);
|
||||
return SessionUser.objects.self_serve_conditions.functions.getConditionName(id);
|
||||
}
|
||||
},
|
||||
order_priority: {
|
||||
|
||||
+17
-1
@@ -114,7 +114,11 @@ import DepartmentWashLane from "@/views/dashboards/departmentDashboard/modules/w
|
||||
import DepartmentSelfServeQuestions
|
||||
from "@/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeQuestions.vue";
|
||||
import DepartmentSelfServeTasks
|
||||
from "@/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeTasks.vue";
|
||||
from "@/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeTasks.vue";
|
||||
import DepartmentSelfServeConditions
|
||||
from "@/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeConditions.vue";
|
||||
import DepartmentSelfServeConditionRules
|
||||
from "@/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeConditionRules.vue";
|
||||
import ConfigurationLimble from "@/views/dashboards/superUserDashboard/configuration/ConfigurationLimble.vue";
|
||||
import MyVehicle from "@/views/dashboards/userDashboard/vehicles/MyVehicle.vue";
|
||||
import XLVaskPage from "@/views/dashboards/superUserDashboard/XLVaskPage.vue";
|
||||
@@ -421,6 +425,18 @@ export const router = createRouter({
|
||||
component: DepartmentSelfServeTasks,
|
||||
meta: { middleware: adminMiddleware, departmentSelection: true }
|
||||
},
|
||||
{
|
||||
name: 'selfserveconditions',
|
||||
path: '/admin/:departmentId/modules/self-serve/conditions',
|
||||
component: DepartmentSelfServeConditions,
|
||||
meta: { middleware: adminMiddleware, departmentSelection: true }
|
||||
},
|
||||
{
|
||||
name: 'selfserveconditionrules',
|
||||
path: '/admin/:departmentId/modules/self-serve/condition-rules',
|
||||
component: DepartmentSelfServeConditionRules,
|
||||
meta: { middleware: adminMiddleware, departmentSelection: true }
|
||||
},
|
||||
{
|
||||
name: 'superuser',
|
||||
path: '/superuser',
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<script setup>
|
||||
import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrapper.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import DepartmentDashboardPageWrapper from "@/views/dashboards/departmentDashboard/DepartmentDashboardPageWrapper.vue";
|
||||
import NotFoundFallBackPageWrapper from "@/components/page/wrappers/NotFoundFallBackPageWrapper.vue";
|
||||
import SelfServeConditionRulesPagination from "@/components/displays/pagination/models/DepartmentDashboard/SelfServeConditionRulesPagination.vue";
|
||||
import PageTitle from "@/components/global/PageTitle.vue";
|
||||
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const departmentId = SessionUser.functions.getDepartmentIdFromUrl();
|
||||
const conditionId = route.query.condition_id;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RestrictedPageWrapper :hasPermission="SessionUser.canAccessAdmin()">
|
||||
<DepartmentDashboardPageWrapper>
|
||||
<NotFoundFallBackPageWrapper :exists="SessionUser.functions.getDepartmentIdFromUrl() && SessionUser.canAccessDepartment(SessionUser.functions.getDepartmentIdFromUrl())" error="Please select a department, that you have access to. If you believe this is an error, please contact support.">
|
||||
<PageTitle :title="SessionUser.objects.self_serve_condition_rules.meta.title" :subtitle="SessionUser.objects.self_serve_condition_rules.meta.description" />
|
||||
|
||||
<SelfServeConditionRulesPagination
|
||||
:set-condition-filter="conditionId"
|
||||
:autoLoad="true"
|
||||
>
|
||||
<template #buttons="{ loadList }">
|
||||
<div class="buttons">
|
||||
<button
|
||||
class="button is-primary"
|
||||
@click="SessionUser.objects.self_serve_condition_rules.showCreateObjectForm({
|
||||
condition_id: conditionId
|
||||
}, loadList)"
|
||||
>
|
||||
<span class="icon">
|
||||
<i class="fas fa-plus"></i>
|
||||
</span>
|
||||
<span>Tilføj regel</span>
|
||||
</button>
|
||||
<router-link :to="{ name: 'selfserveconditions', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-filter"></i>
|
||||
</span>
|
||||
<span>Administrer betingelser</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</SelfServeConditionRulesPagination>
|
||||
</NotFoundFallBackPageWrapper>
|
||||
</DepartmentDashboardPageWrapper>
|
||||
</RestrictedPageWrapper>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrapper.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import DepartmentDashboardPageWrapper from "@/views/dashboards/departmentDashboard/DepartmentDashboardPageWrapper.vue";
|
||||
import NotFoundFallBackPageWrapper from "@/components/page/wrappers/NotFoundFallBackPageWrapper.vue";
|
||||
import SelfServeConditionsPagination from "@/components/displays/pagination/models/DepartmentDashboard/SelfServeConditionsPagination.vue";
|
||||
import PageTitle from "@/components/global/PageTitle.vue";
|
||||
import MyWashStartVehicleTypeSelection from "@/views/dashboards/userDashboard/wash/displays/MyWashStartVehicleTypeSelection.vue";
|
||||
|
||||
const selectedVehicleType = ref(null);
|
||||
const departmentId = SessionUser.functions.getDepartmentIdFromUrl();
|
||||
|
||||
const selectVehicleType = (vehicleType) => {
|
||||
selectedVehicleType.value = vehicleType;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RestrictedPageWrapper :hasPermission="SessionUser.canAccessAdmin()">
|
||||
<DepartmentDashboardPageWrapper>
|
||||
<NotFoundFallBackPageWrapper :exists="SessionUser.functions.getDepartmentIdFromUrl() && SessionUser.canAccessDepartment(SessionUser.functions.getDepartmentIdFromUrl())" error="Please select a department, that you have access to. If you believe this is an error, please contact support.">
|
||||
<PageTitle :title="SessionUser.objects.self_serve_conditions.meta.title" :subtitle="SessionUser.objects.self_serve_conditions.meta.description" />
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title is-5">Vælg køretøjstype</h3>
|
||||
<MyWashStartVehicleTypeSelection @selected="selectVehicleType" :selectedVehicleTypeId="selectedVehicleType?.id" />
|
||||
</div>
|
||||
|
||||
<SelfServeConditionsPagination
|
||||
:setDepartmentFilter="departmentId"
|
||||
:setVehicleTypeFilter="selectedVehicleType?.id"
|
||||
:autoLoad="true"
|
||||
>
|
||||
<template #buttons="{ loadList }">
|
||||
<div class="buttons">
|
||||
<button
|
||||
class="button is-primary"
|
||||
@click="SessionUser.objects.self_serve_conditions.showCreateObjectForm({
|
||||
department: departmentId,
|
||||
product: selectedVehicleType?.id,
|
||||
}, loadList)"
|
||||
:disabled="!selectedVehicleType"
|
||||
:title="!selectedVehicleType ? 'Vælg venligst en køretøjstype først' : ''"
|
||||
>
|
||||
<span class="icon">
|
||||
<i class="fas fa-plus"></i>
|
||||
</span>
|
||||
<span>Tilføj betingelse</span>
|
||||
</button>
|
||||
<router-link :to="{ name: 'selfservequestions', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-question-circle"></i>
|
||||
</span>
|
||||
<span>Administrer spørgsmål</span>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'selfservetasks', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-tasks"></i>
|
||||
</span>
|
||||
<span>Administrer opgaver</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</SelfServeConditionsPagination>
|
||||
</NotFoundFallBackPageWrapper>
|
||||
</DepartmentDashboardPageWrapper>
|
||||
</RestrictedPageWrapper>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
+6
@@ -49,6 +49,12 @@ const selectVehicleType = (vehicleType) => {
|
||||
</span>
|
||||
<span>Tilføj spørgsmål</span>
|
||||
</button>
|
||||
<router-link :to="{ name: 'selfserveconditions', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-filter"></i>
|
||||
</span>
|
||||
<span>Administrer betingelser</span>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'selfservetasks', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-tasks"></i>
|
||||
|
||||
+6
@@ -49,6 +49,12 @@ const selectVehicleType = (vehicleType) => {
|
||||
</span>
|
||||
<span>Tilføj opgave</span>
|
||||
</button>
|
||||
<router-link :to="{ name: 'selfserveconditions', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-filter"></i>
|
||||
</span>
|
||||
<span>Administrer betingelser</span>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'selfservequestions', params: { departmentId: departmentId } }" class="button is-link is-light">
|
||||
<span class="icon">
|
||||
<i class="fas fa-question-circle"></i>
|
||||
|
||||
@@ -8,6 +8,7 @@ import NotFoundFallBackPageWrapper from "@/components/page/wrappers/NotFoundFall
|
||||
import PageTitle from "@/components/global/PageTitle.vue";
|
||||
import SelfServeQuestionsPagination from "@/components/displays/pagination/models/DepartmentDashboard/SelfServeQuestionsPagination.vue";
|
||||
import SelfServeTasksPagination from "@/components/displays/pagination/models/DepartmentDashboard/SelfServeTasksPagination.vue";
|
||||
import SelfServeConditionsPagination from "@/components/displays/pagination/models/DepartmentDashboard/SelfServeConditionsPagination.vue";
|
||||
import MyWashStartVehicleTypeSelection from "@/views/dashboards/userDashboard/wash/displays/MyWashStartVehicleTypeSelection.vue";
|
||||
|
||||
const router = useRouter();
|
||||
@@ -135,6 +136,32 @@ onMounted(() => {
|
||||
<h3 class="title is-5">Vælg køretøjstype</h3>
|
||||
<MyWashStartVehicleTypeSelection @selected="selectVehicleType" :selectedVehicleTypeId="selectedVehicleType?.id" />
|
||||
</div>
|
||||
<div class="box">
|
||||
<SelfServeConditionsPagination
|
||||
:set-department-filter="departmentId"
|
||||
:set-lane-filter="laneId"
|
||||
:set-vehicle-type-filter="selectedVehicleType?.id"
|
||||
:auto-load="true"
|
||||
>
|
||||
<template #buttons="{ loadList }">
|
||||
<button
|
||||
class="button is-primary"
|
||||
@click="SessionUser.objects.self_serve_conditions.showCreateObjectForm({
|
||||
department: departmentId,
|
||||
lane: laneId,
|
||||
product: selectedVehicleType?.id
|
||||
}, loadList)"
|
||||
:disabled="!selectedVehicleType"
|
||||
:title="!selectedVehicleType ? 'Vælg venligst en køretøjstype først' : ''"
|
||||
>
|
||||
<span class="icon">
|
||||
<i class="fas fa-plus"></i>
|
||||
</span>
|
||||
<span>Tilføj betingelse</span>
|
||||
</button>
|
||||
</template>
|
||||
</SelfServeConditionsPagination>
|
||||
</div>
|
||||
<div class="box">
|
||||
<SelfServeQuestionsPagination
|
||||
ref="selfServeQuestionsPagination"
|
||||
|
||||
Reference in New Issue
Block a user