Skip to content

Commit b0f61e7

Browse files
committed
code working withtou RLS activated
1 parent 1be2eb0 commit b0f61e7

File tree

10 files changed

+321
-13
lines changed

10 files changed

+321
-13
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Launch and Debug Standalone Blazor WebAssembly App",
6+
"type": "blazorwasm",
7+
"request": "launch",
8+
"cwd": "${workspaceFolder}"
9+
}
10+
]
11+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "build",
6+
"command": "dotnet",
7+
"type": "process",
8+
"args": [
9+
"build",
10+
"${workspaceFolder}/BlazorWebAssemblySupabaseTemplate.csproj",
11+
"/property:GenerateFullPaths=true",
12+
"/consoleloggerparameters:NoSummary"
13+
],
14+
"problemMatcher": "$msCompile"
15+
},
16+
{
17+
"label": "publish",
18+
"command": "dotnet",
19+
"type": "process",
20+
"args": [
21+
"publish",
22+
"${workspaceFolder}/BlazorWebAssemblySupabaseTemplate.csproj",
23+
"/property:GenerateFullPaths=true",
24+
"/consoleloggerparameters:NoSummary"
25+
],
26+
"problemMatcher": "$msCompile"
27+
},
28+
{
29+
"label": "watch",
30+
"command": "dotnet",
31+
"type": "process",
32+
"args": [
33+
"watch",
34+
"run",
35+
"--project",
36+
"${workspaceFolder}/BlazorWebAssemblySupabaseTemplate.csproj"
37+
],
38+
"problemMatcher": "$msCompile"
39+
}
40+
]
41+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using Postgrest.Attributes;
3+
using Postgrest.Models;
4+
using Supabase;
5+
6+
namespace BlazorWebAssemblySupabaseTemplate.Dtos;
7+
8+
[Table("TodoPrivate")]
9+
public class TodoPrivate : BaseModel
10+
{
11+
[PrimaryKey("id", false)] // Key is Autogenerated
12+
public int Id { get; set; }
13+
14+
[Column("title")]
15+
public string? Title { get; set; }
16+
17+
[Column("user_id")]
18+
public string User_id { get; set; }
19+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
@page "/crud-private"
2+
@using Dtos
3+
@using Blazored.LocalStorage
4+
5+
@inject DatabaseService DatabaseService
6+
@inject NavigationManager NavigationManager
7+
@inject ISnackbar Snackbar
8+
@inject ILocalStorageService localStorage
9+
10+
<div class="pa-16">
11+
12+
<MudText Typo="Typo.h5">Todos private by RLS</MudText>
13+
<br>
14+
<MudForm @ref="form" @bind-IsValid="@success" @bind-Errors="@errors" ValidationDelay="0">
15+
<MudCard>
16+
<MudCardHeader>
17+
<CardHeaderContent>
18+
<h4>New item</h4>
19+
</CardHeaderContent>
20+
</MudCardHeader>
21+
<MudCardContent>
22+
<MudTextField Label="Title" @bind-Value="model.Title" For="@(() => model.Title)" Required="true"
23+
Immediate="true" />
24+
</MudCardContent>
25+
<MudCardActions>
26+
<MudButton Variant="Variant.Filled" Color="Color.Primary" Disabled="@(!success)" Class="ml-auto"
27+
OnClick="OnClickSave">
28+
@if (_processingNewItem)
29+
{
30+
<MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true" />
31+
<MudText Class="ms-2">Processing</MudText>
32+
}
33+
else
34+
{
35+
<MudText>Save</MudText>
36+
}
37+
</MudButton>
38+
</MudCardActions>
39+
40+
</MudCard>
41+
</MudForm>
42+
43+
<br>
44+
45+
@if (_todoListFiltered == null)
46+
{
47+
<MudSimpleTable>
48+
<thead>
49+
<tr>
50+
<th>Title</th>
51+
<th>Action</th>
52+
</tr>
53+
</thead>
54+
<tbody>
55+
<tr>
56+
<td><MudSkeleton /></td>
57+
<td><MudSkeleton /></td>
58+
</tr>
59+
</tbody>
60+
</MudSimpleTable>
61+
}
62+
else if (_todoListFiltered.Count == 0)
63+
{
64+
<MudSimpleTable>
65+
<thead>
66+
<tr>
67+
<th>Title</th>
68+
<th>Action</th>
69+
</tr>
70+
</thead>
71+
<tbody>
72+
<br>
73+
<MudText Typo="Typo.body1" Align="Align.Center">There is no items in this table.</MudText>
74+
<br>
75+
</tbody>
76+
</MudSimpleTable>
77+
}
78+
else
79+
{
80+
<MudTable Items="@_todoListFiltered" @ref="table" Elevation="1" Bordered="false" Striped="true" Hover="true"
81+
SortLabel="Sort By" T="TodoPrivate">
82+
<ToolBarContent>
83+
<MudTextField T="string" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search"
84+
IconSize="MudBlazor.Size.Medium" Class="mt-0" Clearable="true"
85+
ValueChanged="@(s=>OnValueChangedSearch(s))" Placeholder="Search" />
86+
</ToolBarContent>
87+
<HeaderContent>
88+
<MudTh>
89+
<MudTableSortLabel SortBy="new Func<TodoPrivate, object>(x=>x.Title)">
90+
Title
91+
</MudTableSortLabel>
92+
<MudTableSortLabel SortBy="new Func<TodoPrivate, object>(x=>x.User_id)">
93+
User_id
94+
</MudTableSortLabel>
95+
</MudTh>
96+
<MudTh>
97+
Action
98+
</MudTh>
99+
</HeaderContent>
100+
<RowTemplate>
101+
<MudTd DataLabel="Title">@context?.Title</MudTd>
102+
<MudTd DataLabel="User_id">@context?.User_id</MudTd>
103+
<MudTd DataLabel="Action">
104+
@* <MudIconButton Icon="@Icons.Material.Filled.Edit" aria-label="edit"
105+
Size="MudBlazor.Size.Small"
106+
OnClick="@( (e) => {NavigationManager.NavigateTo($"/todoitems/{context?.Todo?.Id}");})"
107+
/> *@
108+
<MudIconButton Icon="@Icons.Material.Filled.Delete" aria-label="delete" Size="MudBlazor.Size.Small"
109+
OnClick="@(async (e) => {await OnClickDelete(context);})" />
110+
</MudTd>
111+
</RowTemplate>
112+
<PagerContent>
113+
<MudTablePager PageSizeOptions="new int[]{50, 100}" />
114+
</PagerContent>
115+
</MudTable>
116+
}
117+
118+
</div>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using BlazorWebAssemblySupabaseTemplate.Dtos;
2+
using BlazorWebAssemblySupabaseTemplate.Services;
3+
using MudBlazor;
4+
5+
namespace BlazorWebAssemblySupabaseTemplate.Pages.CrudPrivate;
6+
7+
public partial class CrudPagePrivate
8+
{
9+
protected override async Task OnInitializedAsync()
10+
{
11+
await GetTable();
12+
}
13+
14+
// ---------------- SELECT TABLE
15+
private IReadOnlyList<TodoPrivate>? _todoList { get; set; }
16+
private IReadOnlyList<TodoPrivate>? _todoListFiltered { get; set; }
17+
private MudTable<TodoPrivate>? table;
18+
protected async Task GetTable()
19+
{
20+
// await Task.Delay(10000);
21+
IReadOnlyList<TodoPrivate> todos = await DatabaseService.From<TodoPrivate>();
22+
_todoList = todos;
23+
_todoListFiltered = todos;
24+
await InvokeAsync(StateHasChanged);
25+
}
26+
27+
// ---------------- SEARCH
28+
private void OnValueChangedSearch(string text)
29+
{
30+
_todoListFiltered = _todoList?.Where(row => row.Title.Contains(text)).ToList();
31+
}
32+
33+
// ---------------- DELETE
34+
private async Task OnClickDelete(TodoPrivate item)
35+
{
36+
await DatabaseService.Delete<TodoPrivate>(item);
37+
await GetTable();
38+
}
39+
40+
// ---------------- CREATE NEW
41+
42+
protected TodoPrivate model = new();
43+
private bool success = false;
44+
string[] errors = { };
45+
MudForm? form;
46+
private bool _processingNewItem = false;
47+
private async Task OnClickSave()
48+
{
49+
string user_id = await localStorage.GetItemAsync<string>("user_id");
50+
51+
model.User_id = user_id;
52+
_processingNewItem = true;
53+
await DatabaseService.Insert<TodoPrivate>(model);
54+
model = new();
55+
await GetTable();
56+
success = false;
57+
_processingNewItem = false;
58+
}
59+
}

Examples/BlazorWebAssemblySupabaseTemplate/Program.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,24 @@
3737
var url = "https://pylnesfgmytjegzzculn.supabase.co";
3838
var key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InB5bG5lc2ZnbXl0amVnenpjdWxuIiwicm9sZSI6ImFub24iLCJpYXQiOjE2NjgyOTMwMzcsImV4cCI6MTk4Mzg2OTAzN30.kI29Q_qYWDH5SD6oi5NTwHG6Pxy1e1AUfR8s_ga45lE";
3939

40-
builder.Services.AddScoped<ISupabaseClient<User, Session, Socket, Channel, Bucket, FileObject>>(args => new Supabase.Client(url, key, new Supabase.SupabaseOptions { AutoConnectRealtime = true }));
40+
builder.Services.AddScoped<ISupabaseClient<User, Session, Socket, Channel, Bucket, FileObject>>(
41+
provider => new Supabase.Client(
42+
url,
43+
key,
44+
new Supabase.SupabaseOptions
45+
{
46+
AutoRefreshToken = true,
47+
AutoConnectRealtime = true,
48+
PersistSession = true,
49+
SessionHandler = new CustomSupabaseSessionHandler(
50+
provider.GetRequiredService<ILocalStorageService>(),
51+
provider.GetRequiredService<ILogger<CustomSupabaseSessionHandler>>()
52+
)
53+
}
54+
)
55+
);
56+
57+
// builder.Services.AddScoped<ISupabaseClient<User, Session, Socket, Channel, Bucket, FileObject>>(args => new Supabase.Client(url, key, new Supabase.SupabaseOptions { AutoConnectRealtime = true }));
4158
builder.Services.AddScoped<AuthService>();
4259
builder.Services.AddScoped<DatabaseService>();
4360

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Blazored.LocalStorage;
2+
using Supabase.Gotrue;
3+
using Supabase.Interfaces;
4+
5+
namespace BlazorWebAssemblySupabaseTemplate.Providers;
6+
7+
public class CustomSupabaseSessionHandler : ISupabaseSessionHandler
8+
{
9+
private readonly ILocalStorageService localStorage;
10+
private readonly ILogger<CustomSupabaseSessionHandler> logger;
11+
12+
public CustomSupabaseSessionHandler(
13+
ILocalStorageService localStorage,
14+
ILogger<CustomSupabaseSessionHandler> logger
15+
)
16+
{
17+
logger.LogInformation("------------------- CONSTRUCTOR -------------------");
18+
this.localStorage = localStorage;
19+
this.logger = logger;
20+
}
21+
22+
public async Task<bool> SessionDestroyer()
23+
{
24+
logger.LogInformation("------------------- SessionDestroyer -------------------");
25+
await localStorage.RemoveItemAsync("SUPABASE_SESSION");
26+
return true;
27+
}
28+
29+
public async Task<bool> SessionPersistor<TSession>(TSession session) where TSession : Session
30+
{
31+
logger.LogInformation("------------------- SessionPersistor -------------------");
32+
await localStorage.SetItemAsync("SUPABASE_SESSION", session);
33+
return true;
34+
}
35+
36+
public async Task<TSession?> SessionRetriever<TSession>() where TSession : Session
37+
{
38+
logger.LogInformation("------------------- SessionRetriever -------------------");
39+
return (TSession?) await localStorage.GetItemAsync<Session>("SUPABASE_SESSION");
40+
}
41+
}

Examples/BlazorWebAssemblySupabaseTemplate/Services/AuthService.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,15 @@ public AuthService(
2222
ILogger<AuthService> logger
2323
) : base()
2424
{
25-
logger.LogInformation("CONSTRUCTOR: AuthService");
25+
logger.LogInformation("------------------- CONSTRUCTOR -------------------");
2626

2727
this.client = client;
2828
customAuthStateProvider = CustomAuthStateProvider;
2929
this.localStorage = localStorage;
3030
this.logger = logger;
3131

32-
if( client.Auth == null)
33-
{
34-
client.InitializeAsync();
35-
}
32+
client.InitializeAsync();
33+
client.Auth.RetrieveSessionAsync();
3634
}
3735

3836
public async Task Login(string email, string password)
@@ -42,9 +40,12 @@ public async Task Login(string email, string password)
4240
Session? session = await client.Auth.SignIn(email, password);
4341

4442
logger.LogInformation("------------------- User logged in -------------------");
45-
logger.LogInformation($"instance.Auth.CurrentUser.Id {client?.Auth?.CurrentUser?.Id}");
43+
// logger.LogInformation($"instance.Auth.CurrentUser.Id {client?.Auth?.CurrentUser?.Id}");
4644
logger.LogInformation($"client.Auth.CurrentUser.Email {client?.Auth?.CurrentUser?.Email}");
4745

46+
logger.LogInformation($"session?.User?.Id {session?.User?.Id}");
47+
await localStorage.SetItemAsStringAsync("user_id", session?.User?.Id);
48+
4849
await localStorage.SetItemAsStringAsync("token", session?.AccessToken);
4950
await customAuthStateProvider.GetAuthenticationStateAsync();
5051
}

Examples/BlazorWebAssemblySupabaseTemplate/Services/DatabaseService.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,15 @@ public DatabaseService(
2323
ILogger<DatabaseService> logger
2424
) : base()
2525
{
26-
logger.LogInformation("CONSTRUCTOR: DatabaseService");
26+
logger.LogInformation("------------------- CONSTRUCTOR -------------------");
2727

2828
this.client = client;
2929
customAuthStateProvider = CustomAuthStateProvider;
3030
this.localStorage = localStorage;
3131
this.logger = logger;
3232

33-
if( client.Postgrest == null)
34-
{
35-
client.InitializeAsync();
36-
}
33+
client.InitializeAsync();
34+
client.Auth.RetrieveSessionAsync();
3735
}
3836

3937
public async Task<IReadOnlyList<TModel>> From<TModel>() where TModel : BaseModel, new()

Examples/BlazorWebAssemblySupabaseTemplate/Shared/MainLayout.razor

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@
3636
@* ********************************** MENU ********************************** *@
3737

3838
<MudNavMenu Color="Color.Secondary">
39-
<MudNavLink Href="/crud" Match="NavLinkMatch.Prefix" Icon="@Icons.Filled.Storage">
39+
<MudNavLink Href="/crud" Match="NavLinkMatch.All" Icon="@Icons.Filled.Storage">
4040
Crud table
4141
</MudNavLink>
42+
<MudNavLink Href="/crud-private" Match="NavLinkMatch.All" Icon="@Icons.Filled.Storage">
43+
Crud table private RLS
44+
</MudNavLink>
4245
</MudNavMenu>
4346

4447

0 commit comments

Comments
 (0)