Introduce event categories

Closes #1056

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2022-03-28 17:42:59 +02:00
parent 91ed13d5c2
commit f5bdedf789
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
21 changed files with 371 additions and 77 deletions

View file

@ -17,7 +17,8 @@ span.tag {
background: $purple-3; background: $purple-3;
color: $violet-2; color: $violet-2;
text-transform: uppercase; text-transform: uppercase;
&::before {
&:not(.category)::before {
content: "#"; content: "#";
} }
} }

View file

@ -23,6 +23,7 @@ const FULL_EVENT_FRAGMENT = gql`
joinOptions joinOptions
draft draft
language language
category
picture { picture {
id id
url url
@ -203,7 +204,7 @@ export const CREATE_EVENT = gql`
$picture: MediaInput $picture: MediaInput
$onlineAddress: String $onlineAddress: String
$phoneAddress: String $phoneAddress: String
$category: String $category: EventCategory
$physicalAddress: AddressInput $physicalAddress: AddressInput
$options: EventOptionsInput $options: EventOptionsInput
$contacts: [Contact] $contacts: [Contact]
@ -253,7 +254,7 @@ export const EDIT_EVENT = gql`
$phoneAddress: String $phoneAddress: String
$organizerActorId: ID $organizerActorId: ID
$attributedToId: ID $attributedToId: ID
$category: String $category: EventCategory
$physicalAddress: AddressInput $physicalAddress: AddressInput
$options: EventOptionsInput $options: EventOptionsInput
$contacts: [Contact] $contacts: [Contact]

View file

@ -11,6 +11,7 @@ export const SEARCH_EVENTS_AND_GROUPS = gql`
$tags: String $tags: String
$term: String $term: String
$type: EventType $type: EventType
$category: String
$beginsOn: DateTime $beginsOn: DateTime
$endsOn: DateTime $endsOn: DateTime
$eventPage: Int $eventPage: Int
@ -23,6 +24,7 @@ export const SEARCH_EVENTS_AND_GROUPS = gql`
tags: $tags tags: $tags
term: $term term: $term
type: $type type: $type
category: $category
beginsOn: $beginsOn beginsOn: $beginsOn
endsOn: $endsOn endsOn: $endsOn
page: $eventPage page: $eventPage

View file

@ -1306,5 +1306,23 @@
"IP Address": "IP Address", "IP Address": "IP Address",
"Last seen on": "Last seen on", "Last seen on": "Last seen on",
"No user matches the filters": "No user matches the filters", "No user matches the filters": "No user matches the filters",
"Reset filters": "Reset filters" "Reset filters": "Reset filters",
"Arts": "Arts",
"Book Clubs": "Book Clubs",
"Business": "Business",
"Causes": "Causes",
"Comedy": "Comedy",
"Crafts": "Crafts",
"Food & Drink": "Food & Drink",
"Health": "Health",
"Music": "Music",
"Auto, Boat & Air": "Auto, Boat & Air",
"Community": "Community",
"Family & Education": "Family & Education",
"Fashion & Beauty": "Fashion & Beauty",
"Film & Media": "Film & Media",
"Games": "Games",
"Category": "Category",
"Select a category": "Select a category",
"Any category": "Any category"
} }

View file

@ -1305,5 +1305,23 @@
"{timezoneLongName} ({timezoneShortName})": "{timezoneLongName} ({timezoneShortName})", "{timezoneLongName} ({timezoneShortName})": "{timezoneLongName} ({timezoneShortName})",
"{title} ({count} todos)": "{title} ({count} todos)", "{title} ({count} todos)": "{title} ({count} todos)",
"{username} was invited to {group}": "{username} a été invité à {group}", "{username} was invited to {group}": "{username} a été invité à {group}",
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap" "© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap",
"Arts": "Arts",
"Book Clubs": "Clubs de lecture",
"Business": "Entreprises",
"Causes": "Causes",
"Comedy": "Comédie",
"Crafts": "Artisanat",
"Food & Drink": "Alimentation et boissons",
"Health": "Santé",
"Music": "Musique",
"Auto, Boat & Air": "Automobile, bateaux et aéronautique",
"Community": "Communauté",
"Family & Education": "Famille et éducation",
"Fashion & Beauty": "Mode et beauté",
"Film & Media": "Films et médias",
"Games": "Jeux",
"Category": "Catégorie",
"Select a category": "Choisissez une categorie",
"Any category": "N'importe quelle catégorie"
} }

View file

@ -72,14 +72,6 @@ export enum EventVisibilityJoinOptions {
LIMITED = "LIMITED", LIMITED = "LIMITED",
} }
export enum Category {
BUSINESS = "business",
CONFERENCE = "conference",
BIRTHDAY = "birthday",
DEMONSTRATION = "demonstration",
MEETING = "meeting",
}
export enum LoginErrorCode { export enum LoginErrorCode {
NEED_TO_LOGIN = "need_to_login", NEED_TO_LOGIN = "need_to_login",
} }

View file

@ -53,6 +53,7 @@ interface IEventEditJSON {
options: IEventOptions; options: IEventOptions;
contacts: { id?: string }[]; contacts: { id?: string }[];
metadata: IEventMetadata[]; metadata: IEventMetadata[];
category: string;
} }
export interface IEvent { export interface IEvent {
@ -91,6 +92,7 @@ export interface IEvent {
metadata: IEventMetadata[]; metadata: IEventMetadata[];
contacts: IActor[]; contacts: IActor[];
language: string; language: string;
category: string;
toEditJSON(): IEventEditJSON; toEditJSON(): IEventEditJSON;
} }
@ -166,6 +168,8 @@ export class EventModel implements IEvent {
metadata: IEventMetadata[] = []; metadata: IEventMetadata[] = [];
category = "MEETING";
constructor(hash?: IEvent | IEditableEvent) { constructor(hash?: IEvent | IEditableEvent) {
if (!hash) return; if (!hash) return;
@ -214,6 +218,7 @@ export class EventModel implements IEvent {
this.tags = hash.tags; this.tags = hash.tags;
this.metadata = hash.metadata; this.metadata = hash.metadata;
this.language = hash.language; this.language = hash.language;
this.category = hash.category;
if (hash.options) this.options = hash.options; if (hash.options) this.options = hash.options;
} }
@ -240,6 +245,7 @@ export function toEditJSON(event: IEditableEvent): IEventEditJSON {
beginsOn: event.beginsOn ? event.beginsOn.toISOString() : null, beginsOn: event.beginsOn ? event.beginsOn.toISOString() : null,
endsOn: event.endsOn ? event.endsOn.toISOString() : null, endsOn: event.endsOn ? event.endsOn.toISOString() : null,
status: event.status, status: event.status,
category: event.category,
visibility: event.visibility, visibility: event.visibility,
joinOptions: event.joinOptions, joinOptions: event.joinOptions,
draft: event.draft, draft: event.draft,

View file

@ -0,0 +1,68 @@
import { i18n } from "@/utils/i18n";
export const eventCategories = [
{
id: "ARTS",
label: i18n.t("Arts"),
icon: "palette",
},
{
id: "BOOK_CLUBS",
label: i18n.t("Book Clubs"),
icon: "favourite-book",
},
{
id: "BUSINESS",
label: i18n.t("Business"),
},
{
id: "CAUSES",
label: i18n.t("Causes"),
},
{
id: "COMEDY",
label: i18n.t("Comedy"),
},
{
id: "CRAFTS",
label: i18n.t("Crafts"),
},
{
id: "FOOD_DRINK",
label: i18n.t("Food & Drink"),
},
{
id: "HEALTH",
label: i18n.t("Health"),
},
{
id: "MUSIC",
label: i18n.t("Music"),
},
{
id: "AUTO_BOAT_AIR",
label: i18n.t("Auto, Boat & Air"),
},
{
id: "COMMUNITY",
label: i18n.t("Community"),
},
{
id: "FAMILY_EDUCATION",
label: i18n.t("Family & Education"),
},
{
id: "FASHION_BEAUTY",
label: i18n.t("Fashion & Beauty"),
},
{
id: "FILM_MEDIA",
label: i18n.t("Film & Media"),
},
{
id: "GAMES",
label: i18n.t("Games"),
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
].sort(({ label: label1 }, { label: label2 }) => label1.localeCompare(label2));

View file

@ -32,7 +32,28 @@
/> />
</b-field> </b-field>
<tag-input v-model="event.tags" /> <div class="flex flex-wrap gap-4">
<b-field
:label="$t('Category')"
label-for="category"
class="w-full md:max-w-fit"
>
<b-select
:placeholder="$t('Select a category')"
v-model="event.category"
expanded
>
<option
v-for="category in eventCategories"
:value="category.id"
:key="category.id"
>
{{ category.label }}
</option>
</b-select>
</b-field>
<tag-input v-model="event.tags" class="flex-1" />
</div>
<b-field <b-field
horizontal horizontal
@ -644,6 +665,7 @@ import { USER_SETTINGS } from "@/graphql/user";
import { IUser } from "@/types/current-user.model"; import { IUser } from "@/types/current-user.model";
import { IAddress } from "@/types/address.model"; import { IAddress } from "@/types/address.model";
import { LOGGED_USER_PARTICIPATIONS } from "@/graphql/participant"; import { LOGGED_USER_PARTICIPATIONS } from "@/graphql/participant";
import { eventCategories } from "@/utils/categories";
const DEFAULT_LIMIT_NUMBER_OF_PLACES = 10; const DEFAULT_LIMIT_NUMBER_OF_PLACES = 10;
@ -753,6 +775,8 @@ export default class EditEvent extends Vue {
formatList = formatList; formatList = formatList;
eventCategories = eventCategories;
@Watch("eventId", { immediate: true }) @Watch("eventId", { immediate: true })
resetFormForCreation(eventId: string): void { resetFormForCreation(eventId: string): void {
if (eventId === undefined) { if (eventId === undefined) {
@ -1059,22 +1083,6 @@ export default class EditEvent extends Vue {
options: this.eventOptions, options: this.eventOptions,
}; };
console.debug(this.event.beginsOn?.toISOString());
// if (this.event.beginsOn && this.timezone) {
// console.debug(
// "begins on should be",
// zonedTimeToUtc(this.event.beginsOn, this.timezone).toISOString()
// );
// }
// if (this.event.beginsOn && this.timezone) {
// res.beginsOn = zonedTimeToUtc(
// this.event.beginsOn,
// this.timezone
// ).toISOString();
// }
const organizerActor = this.event.organizerActor?.id const organizerActor = this.event.organizerActor?.id
? this.event.organizerActor ? this.event.organizerActor
: this.organizerActor; : this.organizerActor;

View file

@ -44,11 +44,10 @@
</popover-actor-card> </popover-actor-card>
</span> </span>
</div> </div>
<p <p class="tags" dir="auto">
class="tags" <tag v-if="eventCategory" class="category">{{
v-if="event.tags && event.tags.length > 0" eventCategory
dir="auto" }}</tag>
>
<router-link <router-link
v-for="tag in event.tags" v-for="tag in event.tags"
:key="tag.title" :key="tag.title"
@ -508,6 +507,7 @@ import { IEventMetadataDescription } from "@/types/event-metadata";
import { eventMetaDataList } from "../../services/EventMetadata"; import { eventMetaDataList } from "../../services/EventMetadata";
import { USER_SETTINGS } from "@/graphql/user"; import { USER_SETTINGS } from "@/graphql/user";
import { IUser } from "@/types/current-user.model"; import { IUser } from "@/types/current-user.model";
import { eventCategories } from "@/utils/categories";
// noinspection TypeScriptValidateTypes // noinspection TypeScriptValidateTypes
@Component({ @Component({
@ -1133,6 +1133,15 @@ export default class Event extends EventMixin {
get routingType(): string | undefined { get routingType(): string | undefined {
return this.config?.maps?.routing?.type; return this.config?.maps?.routing?.type;
} }
get eventCategory(): string | undefined {
if (this.event?.category === "MEETING") {
return undefined;
}
return eventCategories.find((eventCategory) => {
return eventCategory.id === this.event?.category;
})?.label as string;
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View file

@ -92,6 +92,30 @@
</option> </option>
</b-select> </b-select>
</b-field> </b-field>
<b-field
expanded
:label="$t('Category')"
label-for="category"
class="searchCategory"
>
<b-select
expanded
v-model="eventCategory"
id="category"
:disabled="activeTab !== 0"
>
<option :value="null">
{{ $t("Any category") }}
</option>
<option
:value="category.id"
v-for="category in eventCategories"
:key="category.id"
>
{{ category.label }}
</option>
</b-select>
</b-field>
</form> </form>
</div> </div>
</section> </section>
@ -223,6 +247,7 @@ import { REVERSE_GEOCODE } from "../graphql/address";
import debounce from "lodash/debounce"; import debounce from "lodash/debounce";
import { CURRENT_USER_CLIENT } from "@/graphql/user"; import { CURRENT_USER_CLIENT } from "@/graphql/user";
import { ICurrentUser } from "@/types/current-user.model"; import { ICurrentUser } from "@/types/current-user.model";
import { eventCategories } from "@/utils/categories";
interface ISearchTimeOption { interface ISearchTimeOption {
label: string; label: string;
@ -364,6 +389,8 @@ export default class Search extends Vue {
GROUP_PAGE_LIMIT = GROUP_PAGE_LIMIT; GROUP_PAGE_LIMIT = GROUP_PAGE_LIMIT;
eventCategories = eventCategories;
$refs!: { $refs!: {
aac: FullAddressAutoComplete; aac: FullAddressAutoComplete;
autocompleteSearchInput: any; autocompleteSearchInput: any;
@ -511,6 +538,23 @@ export default class Search extends Vue {
}); });
} }
get eventCategory(): string | null {
return (this.$route.query.eventCategory as string) || null;
}
set eventCategory(eventCategory: string | null) {
let query = { ...this.$route.query, eventCategory };
if (query.eventCategory === null) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
delete query.eventCategory;
}
this.$router.replace({
name: RouteName.SEARCH,
query,
});
}
get weekend(): { start: Date; end: Date } { get weekend(): { start: Date; end: Date } {
const now = new Date(); const now = new Date();
const endOfWeekDate = endOfWeek(now, { locale: this.$dateFnsLocale }); const endOfWeekDate = endOfWeek(now, { locale: this.$dateFnsLocale });
@ -642,36 +686,16 @@ h3.title {
} }
form { form {
// ::v-deep .field label.label {
// margin-bottom: 0;
// }
// .field.is-expanded:last-child > .field-body > .field.is-grouped {
// flex-wrap: wrap;
// flex: 1;
// .field {
// flex: 1 0 auto;
// &:first-child {
// flex: 3 0 300px;
// }
// }
// }
display: grid; display: grid;
grid-gap: 0 15px; grid-gap: 0 15px;
grid-template-areas: "query" "location" "radius" "date" "type"; grid-template-areas: "query" "location" "radius" "date" "type" "category";
& > * { & > * {
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
@include tablet {
grid-template-columns: max-content max-content max-content auto;
grid-template-areas: "query . ." "location . ." "radius date type";
}
@include desktop { @include desktop {
grid-template-columns: max-content max-content max-content 1fr 3fr; grid-template-areas: "query . ." "location radius ." "date type category";
grid-template-areas: "query . location" "radius date type";
} }
.searchQuery { .searchQuery {
@ -681,7 +705,7 @@ form {
} }
@include desktop { @include desktop {
grid-column-start: 1; grid-column-start: 1;
grid-column-end: 4; grid-column-end: 5;
} }
} }
@ -694,21 +718,41 @@ form {
grid-column: span 4; grid-column: span 4;
} }
@include desktop { @include desktop {
grid-column-start: 4; grid-column-start: 1;
grid-column-end: 7; grid-column-end: 4;
} }
} }
.searchRadius { .searchRadius {
grid-area: radius; grid-area: radius;
@include desktop {
grid-column-start: 4;
grid-column-end: 5;
}
} }
.searchDate { .searchDate {
grid-area: date; grid-area: date;
@include desktop {
grid-column-start: 1;
grid-column-end: 2;
}
} }
.searchType { .searchType {
grid-area: type; grid-area: type;
@include desktop {
grid-column-start: 2;
grid-column-end: 3;
}
}
.searchCategory {
grid-area: category;
@include desktop {
grid-column-start: 3;
grid-column-end: 5;
}
} }
} }
</style> </style>

View file

@ -22,12 +22,15 @@ defmodule Mobilizon.GraphQL.Schema do
alias Mobilizon.Events.{Event, Participant} alias Mobilizon.Events.{Event, Participant}
alias Mobilizon.GraphQL.Middleware.{CurrentActorProvider, ErrorHandler} alias Mobilizon.GraphQL.Middleware.{CurrentActorProvider, ErrorHandler}
alias Mobilizon.GraphQL.Schema alias Mobilizon.GraphQL.Schema
alias Mobilizon.GraphQL.Schema.Custom
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
@pipeline_modifier Custom.EnumTypes
import_types(Absinthe.Type.Custom) import_types(Absinthe.Type.Custom)
import_types(Absinthe.Plug.Types) import_types(Absinthe.Plug.Types)
import_types(Schema.Custom.UUID) import_types(Custom.UUID)
import_types(Schema.Custom.Point) import_types(Custom.Point)
import_types(Schema.ActivityType) import_types(Schema.ActivityType)
import_types(Schema.UserType) import_types(Schema.UserType)

View file

@ -0,0 +1,109 @@
defmodule Mobilizon.GraphQL.Schema.Custom.EnumTypes do
alias Absinthe.Blueprint.Schema
alias Absinthe.Schema.Notation
alias Absinthe.{Blueprint, Pipeline, Phase}
@categories [
%{
id: :arts,
label: "ARTS"
},
%{
id: :book_clubs,
label: "BOOK_CLUBS"
},
%{
id: :business,
label: "BUSINESS"
},
%{
id: :causes,
label: "CAUSES"
},
%{
id: :comedy,
label: "COMEDY"
},
%{
id: :crafts,
label: "CRAFTS"
},
%{
id: :food_drink,
label: "FOOD_DRINK"
},
%{
id: :health,
label: "HEALTH"
},
%{
id: :music,
label: "MUSIC"
},
%{
id: :auto_boat_air,
label: "AUTO_BOAT_AIR"
},
%{
id: :community,
label: "COMMUNITY"
},
%{
id: :family_education,
label: "FAMILY_EDUCATION"
},
%{
id: :fashion_beauty,
label: "FASHION_BEAUTY"
},
%{
id: :film_media,
label: "FILM_MEDIA"
},
%{
id: :games,
label: "GAMES"
},
# Legacy default value
%{
id: :meeting,
label: "MEETING"
}
]
def pipeline(pipeline) do
Pipeline.insert_after(pipeline, Phase.Schema.TypeImports, __MODULE__)
end
def run(blueprint = %Blueprint{}, _) do
%{schema_definitions: [schema]} = blueprint
new_enum = build_dynamic_enum()
schema =
Map.update!(schema, :type_definitions, fn type_definitions ->
[new_enum | type_definitions]
end)
{:ok, %{blueprint | schema_definitions: [schema]}}
end
def build_dynamic_enum() do
%Schema.EnumTypeDefinition{
name: "EventCategory",
identifier: :event_category,
module: __MODULE__,
__reference__: Notation.build_reference(__ENV__),
values:
Enum.map(@categories, fn %{id: id, label: label} ->
%Schema.EnumValueDefinition{
identifier: id,
value: label,
name: label,
module: __MODULE__,
__reference__: Notation.build_reference(__ENV__)
}
end)
}
end
end

View file

@ -66,7 +66,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
description: "The event's tags" description: "The event's tags"
) )
field(:category, :string, description: "The event's category") field(:category, :event_category, description: "The event's category")
field(:draft, :boolean, description: "Whether or not the event is a draft") field(:draft, :boolean, description: "Whether or not the event is a draft")
@ -399,7 +399,11 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
arg(:attributed_to_id, :id, description: "Who the event is attributed to ID (often a group)") arg(:attributed_to_id, :id, description: "Who the event is attributed to ID (often a group)")
arg(:category, :string, default_value: "meeting", description: "The event's category") arg(:category, :event_category,
default_value: "MEETING",
description: "The event's category"
)
arg(:physical_address, :address_input, description: "The event's physical address") arg(:physical_address, :address_input, description: "The event's physical address")
arg(:options, :event_options_input, default_value: %{}, description: "The event options") arg(:options, :event_options_input, default_value: %{}, description: "The event options")
arg(:metadata, list_of(:event_metadata_input), description: "The event metadata") arg(:metadata, list_of(:event_metadata_input), description: "The event metadata")
@ -448,7 +452,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
arg(:attributed_to_id, :id, description: "Who the event is attributed to ID (often a group)") arg(:attributed_to_id, :id, description: "Who the event is attributed to ID (often a group)")
arg(:category, :string, description: "The event's category") arg(:category, :event_category, description: "The event's category")
arg(:physical_address, :address_input, description: "The event's physical address") arg(:physical_address, :address_input, description: "The event's physical address")
arg(:options, :event_options_input, description: "The event options") arg(:options, :event_options_input, description: "The event options")
arg(:metadata, list_of(:event_metadata_input), description: "The event metadata") arg(:metadata, list_of(:event_metadata_input), description: "The event metadata")

View file

@ -93,6 +93,7 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
arg(:tags, :string, description: "A comma-separated string listing the tags") arg(:tags, :string, description: "A comma-separated string listing the tags")
arg(:location, :string, description: "A geohash for coordinates") arg(:location, :string, description: "A geohash for coordinates")
arg(:type, :event_type, description: "Whether the event is online or in person") arg(:type, :event_type, description: "Whether the event is online or in person")
arg(:category, :string, description: "The category for the event")
arg(:radius, :float, arg(:radius, :float,
default_value: 50, default_value: 50,

View file

@ -54,14 +54,6 @@ defmodule Mobilizon.Events do
:cancelled :cancelled
]) ])
defenum(EventCategory, :event_category, [
:business,
:conference,
:birthday,
:demonstration,
:meeting
])
defenum(ParticipantRole, :participant_role, [ defenum(ParticipantRole, :participant_role, [
:not_approved, :not_approved,
:not_confirmed, :not_confirmed,
@ -536,6 +528,7 @@ defmodule Mobilizon.Events do
|> events_for_search_query() |> events_for_search_query()
|> events_for_begins_on(args) |> events_for_begins_on(args)
|> events_for_ends_on(args) |> events_for_ends_on(args)
|> events_for_category(args)
|> events_for_tags(args) |> events_for_tags(args)
|> events_for_location(args) |> events_for_location(args)
|> filter_online(args) |> filter_online(args)
@ -1313,6 +1306,13 @@ defmodule Mobilizon.Events do
end end
end end
@spec events_for_category(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
defp events_for_category(query, %{category: category}) when is_valid_string(category) do
where(query, [q], q.category == ^category)
end
defp events_for_category(query, _args), do: query
@spec events_for_tags(Ecto.Queryable.t(), map()) :: Ecto.Query.t() @spec events_for_tags(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
defp events_for_tags(query, %{tags: tags}) when is_valid_string(tags) do defp events_for_tags(query, %{tags: tags}) when is_valid_string(tags) do
query query

View file

@ -299,7 +299,6 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Events.Tag, Mobilizon.Events.Tag,
Mobilizon.Events.TagRelations, Mobilizon.Events.TagRelations,
Mobilizon.Events.Track, Mobilizon.Events.Track,
Mobilizon.Events.EventCategory,
Mobilizon.Events.EventStatus, Mobilizon.Events.EventStatus,
Mobilizon.Events.EventVisibility, Mobilizon.Events.EventVisibility,
Mobilizon.Events.JoinOptions, Mobilizon.Events.JoinOptions,

View file

@ -0,0 +1,11 @@
defmodule Mobilizon.Storage.Repo.Migrations.SetAllEventsCategoryToMeeting do
use Ecto.Migration
def up do
Ecto.Migration.execute("UPDATE events SET category = 'MEETING'")
end
def down do
Ecto.Migration.execute("UPDATE events SET category = 'meeting' WHERE category = 'MEETING'")
end
end

View file

@ -21,7 +21,7 @@ defmodule Mobilizon.Web.Resolvers.EventTest do
begins_on: DateTime.utc_now() |> DateTime.truncate(:second), begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
uuid: "b5126423-f1af-43e4-a923-002a03003ba4", uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
url: "some url", url: "some url",
category: "meeting" category: "MEETING"
} }
@find_event_query """ @find_event_query """

View file

@ -20,7 +20,7 @@ defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|> DateTime.truncate(:second), |> DateTime.truncate(:second),
uuid: "b5126423-f1af-43e4-a923-002a03003ba4", uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
url: "some url", url: "some url",
category: "meeting", category: "MEETING",
options: %{} options: %{}
} }

View file

@ -17,7 +17,7 @@ defmodule Mobilizon.EventsTest do
title: "some title", title: "some title",
url: "some url", url: "some url",
uuid: "b5126423-f1af-43e4-a923-002a03003ba4", uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
category: "meeting" category: "MEETING"
} }
describe "list_events/5" do describe "list_events/5" do