owltide/components/RolesTable.vue

160 lines
3.3 KiB
Vue
Raw Normal View History

2025-03-15 15:10:42 +01:00
<template>
<div>
2025-03-15 15:10:42 +01:00
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>description</th>
<th v-if="edit"></th>
</tr>
</thead>
<tbody>
<template v-if="edit">
<tr
v-for="role in schedule.roles.values()"
2025-03-15 15:10:42 +01:00
:key="role.id"
:class="{ removed: role.deleted }"
2025-03-15 15:10:42 +01:00
>
<td>{{ role.id }}</td>
<td>
<input
type="text"
:value="role.name"
@input="editRole(role, { name: ($event as any).target.value })"
>
</td>
<td>
<input
type="text"
:value="role.description"
@input="editRole(role, { description: ($event as any).target.value })"
>
</td>
<td>
<button
type="button"
:disabled="role.deleted"
@click="editRole(role, { deleted: true })"
2025-03-15 15:10:42 +01:00
>Delete</button>
<button
v-if="schedule.isModifiedRole(role.id)"
2025-03-15 15:10:42 +01:00
type="button"
@click="revertRole(role.id)"
>Revert</button>
</td>
</tr>
<tr>
<td>{{ schedule.nextClientId }}</td>
2025-03-15 15:10:42 +01:00
<td>
<input
type="text"
v-model="newRoleName"
>
</td>
<td>
<input
type="text"
v-model="newRoleDescription"
>
</td>
<td>
<button
v-if="roleExists(newRoleName)"
disabled
>Role already exists</button>
<button
v-else
type="button"
@click="newRole"
>Add Role</button>
</td>
</tr>
</template>
<template v-else>
<tr
v-for="role in schedule.roles.values()"
2025-03-15 15:10:42 +01:00
:key="role.id"
>
<td>{{ role.id }}</td>
<td>{{ role.name }}</td>
<td>{{ role.description }}</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
<script lang="ts" setup>
import { DateTime } from '~/shared/utils/luxon';
2025-03-15 15:10:42 +01:00
import { toId } from '~/shared/utils/functions';
import type { Id } from '~/shared/types/common';
2025-03-15 15:10:42 +01:00
defineProps<{
edit?: boolean,
}>();
const schedule = await useSchedule();
const newRoleName = ref("");
const newRoleDescription = ref("");
2025-03-15 15:10:42 +01:00
function editRole(
role: ClientScheduleRole,
edits: { deleted?: boolean, name?: string, description?: string }
2025-03-15 15:10:42 +01:00
) {
const copy = role.clone();
if (edits.deleted !== undefined) copy.deleted = edits.deleted;
if (edits.name !== undefined) copy.name = edits.name;
if (edits.description !== undefined) copy.description = edits.description;
try {
schedule.value.setRole(copy);
} catch (err: any) {
alert(err.message);
2025-03-15 15:10:42 +01:00
}
}
function revertRole(id: Id) {
schedule.value.restoreRole(id);
2025-03-15 15:10:42 +01:00
}
function roleExists(name: string) {
name = toId(name);
2025-03-15 15:10:42 +01:00
return (
[...schedule.value.roles.values()].some(r => !r.deleted && toId(r.name) === name)
2025-03-15 15:10:42 +01:00
);
}
function newRole() {
if (roleExists(newRoleName.value)) {
alert(`Role ${newRoleName.value} already exists`);
return;
}
const role = new ClientScheduleRole(
schedule.value.nextClientId--,
DateTime.now(),
false,
newRoleName.value,
newRoleDescription.value,
);
schedule.value.setRole(role);
2025-03-15 15:10:42 +01:00
newRoleName.value = "";
newRoleDescription.value = "";
}
</script>
<style scoped>
table {
border-spacing: 0;
}
table th {
text-align: left;
border-bottom: 1px solid var(--foreground);
}
table :is(th, td) + :is(th, td) {
padding-inline-start: 0.4em;
}
.removed :is(td, input) {
text-decoration: line-through;
}
</style>