Skip to content

Commit 65f5231

Browse files
authored
Add the ability for song book entries to have videos. (#1067)
* Add the ability for song book entries to have videos. * Add roles for programmes.
1 parent e1f6104 commit 65f5231

File tree

6 files changed

+43
-8
lines changed

6 files changed

+43
-8
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "songs" ADD COLUMN "video" TEXT;

src/database/prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ model Song {
687687
createdAt DateTime? @map("created_at") @db.Timestamptz(6)
688688
updatedAt DateTime? @map("updated_at") @db.Timestamptz(6)
689689
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
690+
video String?
690691
691692
@@map("songs")
692693
}

src/database/schema.zmodel

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ model Author {
186186
// Hide author if the member behind it is currently stab, or if it was posted as a "stab" mandate, AND user does not "see staben"
187187
// There is one exception: If the author is of type "Custom Author" then it is fine to show, as the person behind it is not shown
188188
@@deny("read", type != "Custom" && (
189-
startsWith(mandate.positionId, "dsek.noll.stab.")
189+
startsWith(mandate.positionId, "dsek.noll.stab.")
190190
|| member.mandates?[startDate < now() && now() < endDate && (startsWith(positionId, "dsek.noll.stab."))]
191191
) && !has(auth().policies, "member:see_staben") && auth().memberId != memberId)
192192
}
@@ -512,7 +512,7 @@ model Mandate {
512512
authors Author[]
513513
member Member @relation(fields: [memberId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "mandates_member_id_foreign")
514514
position Position @relation(fields: [positionId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "mandates_position_id_foreign")
515-
515+
516516
// Used on phadder mandates to connect to the phadder group
517517
phadderInId String? @db.Uuid @allow("update", auth().memberId == memberId || has(auth().policies, "nollning:phaddrar:groups:manage"))
518518
phadderIn PhadderGroup? @relation(fields: [phadderInId], references: [id], onDelete: SetNull, onUpdate: NoAction)
@@ -819,6 +819,7 @@ model Song {
819819
createdAt DateTime? @map("created_at") @db.Timestamptz(6)
820820
updatedAt DateTime? @map("updated_at") @db.Timestamptz(6)
821821
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
822+
video String?
822823

823824
@@allow("create", has(auth().policies, "song:create"))
824825
@@allow("read", has(auth().policies, "song:read"))
@@ -948,8 +949,8 @@ model Shoppable {
948949
@@allow("update", auth().memberId == authorId || has(auth().policies, "webshop:manage"))
949950

950951
// I would like to do something like this but it is not possible because has(list: Any[], literal: Any) requires a literal
951-
// @@allow("read", isEmpty(accessPolicies) ||
952-
// accessPolicies?[exists(role != null && has(auth().roles, role)) ||
952+
// @@allow("read", isEmpty(accessPolicies) ||
953+
// accessPolicies?[exists(role != null && has(auth().roles, role)) ||
953954
// (studentId != null && auth().studentId == studentId)])
954955
@@allow("read", true)
955956

@@ -1155,8 +1156,8 @@ model Expense {
11551156
))
11561157
@@allow("update", hasBeenSentToBookkeeping == false && (
11571158
(memberId == auth().memberId)
1158-
|| items?[signerMemberId == auth().memberId]
1159-
|| has(auth().policies, "expenses:bookkeeping")
1159+
|| items?[signerMemberId == auth().memberId]
1160+
|| has(auth().policies, "expenses:bookkeeping")
11601161
))
11611162
@@allow("delete" , false)
11621163

@@ -1183,7 +1184,7 @@ model ExpenseItem {
11831184
@@allow("create", has(auth().policies, "expenses:create") /* && signerMemberId != expense.memberId (TODO: Uncomment this when we upgrade to zenstack v2) */ && signedByMemberId == null && signedAt == null)
11841185
// copy auth from Expense
11851186
@@allow("read", (
1186-
expense.memberId == auth().memberId
1187+
expense.memberId == auth().memberId
11871188
|| expense.items?[signerMemberId == auth().memberId]
11881189
|| has(auth().policies, "expenses:bookkeeping")
11891190
))

src/database/seed/.snaplet/dataModel.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9111,6 +9111,20 @@
91119111
"hasDefaultValue": false,
91129112
"isId": false,
91139113
"maxLength": 255
9114+
},
9115+
{
9116+
"id": "public.songs.video",
9117+
"name": "video",
9118+
"columnName": "video",
9119+
"type": "text",
9120+
"isRequired": false,
9121+
"kind": "scalar",
9122+
"isList": false,
9123+
"isGenerated": false,
9124+
"sequence": false,
9125+
"hasDefaultValue": false,
9126+
"isId": false,
9127+
"maxLength": null
91149128
}
91159129
],
91169130
"uniqueConstraints": [

src/lib/utils/authorization.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,13 @@ export const getDerivedRoles = (
5454
if (groupList?.length || signedIn) splitGroups.add("_"); // logged in users
5555
if (classYear && classYear === new Date().getFullYear())
5656
splitGroups.add("nolla");
57-
if (classYear) {
57+
if (classYear !== undefined) {
5858
const shortYear = String(classYear % 100);
5959
splitGroups.add(classProgramme + shortYear);
6060
}
61+
if (classProgramme !== undefined) {
62+
splitGroups.add(classProgramme);
63+
}
64+
6165
return [...splitGroups];
6266
};

src/routes/(app)/songbook/[slug]/+page.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
import Disclaimer from "../Disclaimer.svelte";
66
import SongElement from "../SongElement.svelte";
77
import * as m from "$paraglide/messages";
8+
import type { AuthUser } from "@zenstackhq/runtime";
89
910
import type { PageData } from "./$types";
1011
export let data: PageData;
12+
13+
// This exist to make svansen of spritbolaget private to members.
14+
function mayWatchVideos(user: AuthUser): boolean {
15+
return user.roles.some((role) => ["C", "D", "VR/AR"].includes(role));
16+
}
1117
</script>
1218

1319
<SetPageTitle title={data.song.title} />
@@ -17,6 +23,13 @@
1723

1824
<SongElement song={data.song} class="my-0 p-0 shadow-none ring-transparent" />
1925

26+
{#if data.song.video !== null && mayWatchVideos(data.user)}
27+
<video controls class="pb-8 pt-8">
28+
<source src={data.song.video} />
29+
<track kind="captions" />
30+
</video>
31+
{/if}
32+
2033
<Disclaimer />
2134

2235
{#if isAuthorized(apiNames.SONG.UPDATE, data.user)}

0 commit comments

Comments
 (0)