Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/493 Study Tags #494

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
f91cce3
feat(#432): dashboard search and filter
johannesvedder Jun 13, 2023
362a4fe
fix: remove Designer V2 version number from page title
johannesvedder Jun 22, 2023
01510b4
feat(#432): dashboard pin and unpin studies
johannesvedder Jun 22, 2023
0c3d225
refactor: rename .env.selfhost to .env.hpi
johannesvedder Jun 22, 2023
9f0e8ac
feat(#432): add pins to study table and refactor code
johannesvedder Jun 23, 2023
eda8ccf
refactor: fix dashboard pin null value
johannesvedder Jun 27, 2023
615d5b6
feat: initial study tags
johannesvedder Jun 27, 2023
2aa65e2
use custom multiselect
johannesvedder Jun 27, 2023
515785b
fix: update copyright
johannesvedder Jun 27, 2023
66ba324
style: typo
johannesvedder Jun 27, 2023
cf39195
fix: tag type
johannesvedder Jun 27, 2023
b96dcf8
feat: display and update tags correctly
johannesvedder Jun 27, 2023
d7cb5f3
refactor: make tags more reactive
johannesvedder Jun 29, 2023
ef7532a
fix: make color nullable and int, add tags to dashboard
johannesvedder Jun 29, 2023
c1bf13d
refactor: rename
johannesvedder Jun 30, 2023
8d4eaa9
feat: working tags with foreign key study_tag
johannesvedder Jun 30, 2023
db57e09
fix: study_tags was null for new studies
johannesvedder Jun 30, 2023
354313c
style: dashboard study rows pin and tags improvement
johannesvedder Jun 30, 2023
59882b7
fix: tag related sql
johannesvedder Jun 30, 2023
73c207f
docs: update database documentation
Jun 30, 2023
0cbb4a6
fix: user related policies
johannesvedder Jun 30, 2023
052f977
fix: add user policy
johannesvedder Jun 30, 2023
9baddd1
fix: tag color
johannesvedder Jun 30, 2023
5729a09
fix: non-working pin
johannesvedder Jun 30, 2023
0bd0b30
docs: update database documentation
Jun 30, 2023
18158bb
chore: format
johannesvedder Jun 30, 2023
95f3306
feat: refactor Search to widget and make tags clickable
johannesvedder Jul 1, 2023
d0a96ea
fix: make Repo urls optional
johannesvedder Jul 1, 2023
324e2ce
fix: study was not returned completely
johannesvedder Jul 1, 2023
2d5076a
Merge branch 'dev' into issue/2-432-feature-designer-dashboard-improv…
johannesvedder Jul 17, 2023
e586369
chore: lock files
johannesvedder Jul 12, 2023
b4a987e
refactor: cleanup
johannesvedder Jul 14, 2023
611541f
fix(#482): docker networks
johannesvedder Jul 17, 2023
f2f8eca
feat: make study tags reactive
johannesvedder Jul 17, 2023
5df6619
remove tag color and parent from schema
johannesvedder Jul 17, 2023
e6579c8
refactor: pin changes to user_repository.dart
johannesvedder Jul 17, 2023
d820e77
chore: format
johannesvedder Jul 17, 2023
39d4a80
feat(#482): add postgresql schema export script
johannesvedder Jul 15, 2023
3989141
feat(#482): dump current schema
johannesvedder Jul 15, 2023
16df2ed
feat(#482): add supabase test framework
johannesvedder Jul 15, 2023
659efc7
fix(#482): docker networks
johannesvedder Jul 17, 2023
3b4a8b1
feat(#482): add more tests
johannesvedder Jul 17, 2023
e8e3fbd
docs: update database documentation
Jul 26, 2023
6a5c606
feat(#482): gh action
johannesvedder Jul 26, 2023
aa9dccb
feat(#482): update supabase image versions and add env subst for kong…
johannesvedder Jul 27, 2023
e66c8b3
Merge branch 'issue/482-supabase-test-framework' into issue/432-featu…
johannesvedder Jul 27, 2023
a47d7fc
feat(#432): partially reactive tags with validation
johannesvedder Jul 27, 2023
1b57070
docs: update database documentation
Jul 27, 2023
c59debb
fix(#432): Move tags to different branch
johannesvedder Jul 30, 2023
052517f
docs: update database documentation
Jul 30, 2023
505d66f
feat(#493): Enable tags again
johannesvedder Jul 30, 2023
8f4ed25
docs: update database documentation
Jul 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/supabase-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Test Supabase
on:
push:
paths:
- "database/**"
- "docker/**"
pull_request:
paths:
- "database/**"
- "docker/**"
workflow_dispatch:

jobs:
pgtap:
runs-on: ubuntu-latest
services:
postgres:
image: supabase/postgres:15.1.0.90
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Seed database
run: cp database/studyu-schema.sql docker/supabase/seed.sql

- name: Set up Supabase CLI
uses: supabase/setup-cli@v1
with:
version: latest

- name: Initialize Supabase
working-directory: docker
run: |
supabase db start

- name: Run Supabase Tests
working-directory: docker
run: |
supabase test db
6 changes: 2 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,8 @@ convenience:

- `.env`: Production database used by default
- `.env.staging`: Staging database, currently not ready to be used
- `.env.local`: Used to run StudyU locally with Docker with the deployed
production instance of Supabase
- `.env.selfhost`: Used for a selfhosted instance of Supabase, e.g. an instance
running locally with Docker
- `.env.local`: Used to run StudyU locally with Docker
- `.env.hpi`: Used for a selfhost instance of Supabase at HPI

Ideally we should only use the staging database or a local one for all our
development work.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,13 @@ class AverageSectionWidget extends ReportSectionWidget {
showTitles: true,
getTitlesWidget: getTitles,
)),
// ignore: prefer_const_constructors
topTitles: AxisTitles(
// ignore: prefer_const_constructors
sideTitles: SideTitles(
showTitles: false,
))),
// ignore: prefer_const_constructors
gridData: charts.FlGridData(
drawHorizontalLine: false,
drawVerticalLine: false,
Expand Down
8 changes: 0 additions & 8 deletions app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.10.2"
freezed_annotation:
dependency: transitive
description:
name: freezed_annotation
sha256: "70776c4541e5cacfe45bcaf00fe79137b8c61aa34fb5765a05ce6c57fd72c6e9"
url: "https://pub.dev"
source: hosted
version: "0.14.3"
functions_client:
dependency: transitive
description:
Expand Down
3 changes: 3 additions & 0 deletions core/lib/src/models/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ export 'tables/repo.dart';
export 'tables/study.dart';
export 'tables/study_invite.dart';
export 'tables/study_subject.dart';
export 'tables/study_tag.dart';
export 'tables/subject_progress.dart';
export 'tables/tag.dart';
export 'tables/user.dart';
export 'tasks/tasks.dart';
4 changes: 2 additions & 2 deletions core/lib/src/models/tables/repo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class Repo extends SupabaseObjectFunctions<Repo> {
String studyId;
GitProvider provider;
@JsonKey(name: 'web_url')
String webUrl;
String? webUrl;
@JsonKey(name: 'git_url')
String gitUrl;
String? gitUrl;

Repo(this.projectId, this.userId, this.studyId, this.provider, this.webUrl, this.gitUrl);

Expand Down
30 changes: 20 additions & 10 deletions core/lib/src/models/tables/repo.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 24 additions & 1 deletion core/lib/src/models/tables/study.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class Study extends SupabaseObjectFunctions<Study> {
@JsonKey(name: 'registry_published')
late bool registryPublished = false;

@JsonKey(includeToJson: false, includeFromJson: false)
List<StudyTag> studyTags = [];
@JsonKey(includeToJson: false, includeFromJson: false)
int participantCount = 0;
@JsonKey(includeToJson: false, includeFromJson: false)
Expand Down Expand Up @@ -99,45 +101,66 @@ class Study extends SupabaseObjectFunctions<Study> {

factory Study.fromJson(Map<String, dynamic> json) {
final study = _$StudyFromJson(json);
final List? studyTags = json['study_tags'] as List?;
if (studyTags != null) {
study.studyTags = studyTags
.map(
(json) => StudyTag.fromTag(
studyId: study.id,
tag: Tag.fromJson(json as Map<String, dynamic>),
),
)
.toList();
}

final List? repo = json['repo'] as List?;
if (repo != null && repo.isNotEmpty) {
study.repo = Repo.fromJson((json['repo'] as List)[0] as Map<String, dynamic>);
}

final List? invites = json['study_invite'] as List?;
if (invites != null) {
study.invites = invites.map((json) => StudyInvite.fromJson(json as Map<String, dynamic>)).toList();
}

final List? participants = json['study_subject'] as List?;
if (participants != null) {
study.participants = participants.map((json) => StudySubject.fromJson(json as Map<String, dynamic>)).toList();
}

List? participantsProgress = json['study_progress'] as List?;
participantsProgress = json['study_progress_export'] as List?;
participantsProgress ??= json['subject_progress'] as List?;
if (participantsProgress != null) {
study.participantsProgress =
participantsProgress.map((json) => SubjectProgress.fromJson(json as Map<String, dynamic>)).toList();
}

final int? participantCount = json['study_participant_count'] as int?;
if (participantCount != null) {
study.participantCount = participantCount;
}

final int? endedCount = json['study_ended_count'] as int?;
if (endedCount != null) {
study.endedCount = endedCount;
}

final int? activeSubjectCount = json['active_subject_count'] as int?;
if (activeSubjectCount != null) {
study.activeSubjectCount = activeSubjectCount;
}

final List? missedDays = json['study_missed_days'] as List?;
if (missedDays != null) {
study.missedDays = List<int>.from(json['study_missed_days'] as List);
}

final String? createdAt = json['created_at'] as String?;
if (createdAt != null && createdAt.isNotEmpty) {
study.createdAt = DateTime.parse(createdAt);
}

return study;
}

Expand Down Expand Up @@ -234,6 +257,6 @@ class Study extends SupabaseObjectFunctions<Study> {

@override
String toString() {
return 'Study{id: $id, title: $title, description: $description, userId: $userId, participation: $participation, resultSharing: $resultSharing, contact: $contact, iconName: $iconName, published: $published, questionnaire: $questionnaire, eligibilityCriteria: $eligibilityCriteria, consent: $consent, interventions: $interventions, observations: $observations, schedule: $schedule, reportSpecification: $reportSpecification, results: $results, collaboratorEmails: $collaboratorEmails, registryPublished: $registryPublished, participantCount: $participantCount, endedCount: $endedCount, activeSubjectCount: $activeSubjectCount, missedDays: $missedDays, repo: $repo, invites: $invites, participants: $participants, participantsProgress: $participantsProgress, createdAt: $createdAt}';
return 'Study{id: $id, title: $title, description: $description, studyTags: $studyTags, userId: $userId, participation: $participation, resultSharing: $resultSharing, contact: $contact, iconName: $iconName, published: $published, questionnaire: $questionnaire, eligibilityCriteria: $eligibilityCriteria, consent: $consent, interventions: $interventions, observations: $observations, schedule: $schedule, reportSpecification: $reportSpecification, results: $results, collaboratorEmails: $collaboratorEmails, registryPublished: $registryPublished, participantCount: $participantCount, endedCount: $endedCount, activeSubjectCount: $activeSubjectCount, missedDays: $missedDays, repo: $repo, invites: $invites, participants: $participants, participantsProgress: $participantsProgress, createdAt: $createdAt}';
}
}
70 changes: 70 additions & 0 deletions core/lib/src/models/tables/study_tag.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:studyu_core/core.dart';

part 'study_tag.g.dart';

@JsonSerializable()
class StudyTag extends SupabaseObjectFunctions<StudyTag> {
static const String tableName = 'study_tag';

@override
Map<String, dynamic> get primaryKeys => {'tag_id': tagId, 'study_id': studyId};

@JsonKey(name: 'study_id')
final String studyId;
@JsonKey(name: 'tag_id')
final String tagId;

@JsonKey(includeToJson: false, includeFromJson: false)
late Tag tag;

/*@JsonKey(includeToJson: false, includeFromJson: false)
late Study study;*/

StudyTag({
required this.studyId,
required this.tagId,
});

StudyTag.fromTag({
required this.tag,
required this.studyId,
}) : tagId = tag.id;

factory StudyTag.fromJson(Map<String, dynamic> json) {
final studyTag = _$StudyTagFromJson(json);

/*final Map<String, dynamic>? study = json['study'] as Map<String, dynamic>?;
if (study != null) {
studyTag.study = Study.fromJson(study);
}*/

final Map<String, dynamic>? tag = json['tag'] as Map<String, dynamic>?;
if (tag != null) {
studyTag.tag = Tag.fromJson(tag);
}

return studyTag;
}

String get name => tag.name;

String get id => tag.id;

@override
Map<String, dynamic> toJson() => _$StudyTagToJson(this);

@override
String toString() => toJson().toString();

@override
bool operator ==(Object other) =>
identical(this, other) || other is StudyTag && studyId == other.studyId && tag == other.tag;

@override
int get hashCode => id.hashCode ^ name.hashCode ^ studyId.hashCode ^ tag.hashCode;
}

extension StudyTagListToTagList on List<StudyTag> {
List<Tag> toTagList() => map((studyTag) => studyTag.tag).toList();
}
17 changes: 17 additions & 0 deletions core/lib/src/models/tables/study_tag.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions core/lib/src/models/tables/tag.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import 'package:json_annotation/json_annotation.dart';

import 'package:studyu_core/core.dart';
import 'package:studyu_core/src/util/supabase_object.dart';

part 'tag.g.dart';

@JsonSerializable()
class Tag extends SupabaseObjectFunctions<Tag> {
static const String tableName = 'tag';

@override
Map<String, dynamic> get primaryKeys => {'id': id};

@JsonKey(name: 'id')
String id;
@JsonKey(name: 'name')
String name;

Tag({required this.id, required this.name});

factory Tag.fromJson(Map<String, dynamic> json) => _$TagFromJson(json);

@override
Map<String, dynamic> toJson() => _$TagToJson(this);

@override
bool operator ==(Object other) =>
identical(this, other) || other is Tag && id == other.id && name == other.name;

@override
int get hashCode => id.hashCode ^ name.hashCode;
}
17 changes: 17 additions & 0 deletions core/lib/src/models/tables/tag.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading