fix: compile error + notif binding issue
This commit is contained in:
parent
a11c58274c
commit
1602aa9556
@ -15,7 +15,7 @@
|
||||
maxlength="64"
|
||||
:placeholder="`Enter organization name...`"
|
||||
autocomplete="off"
|
||||
@input="updateSlug()"
|
||||
@input="updateSlug"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@ -33,7 +33,7 @@
|
||||
type="text"
|
||||
maxlength="64"
|
||||
autocomplete="off"
|
||||
@input="manualSlug = true"
|
||||
@input="setManualSlug"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,7 +61,7 @@
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button @click="modal.hide()">
|
||||
<button @click="hide">
|
||||
<XIcon aria-hidden="true" />
|
||||
Cancel
|
||||
</button>
|
||||
@ -70,21 +70,22 @@
|
||||
</div>
|
||||
</NewModal>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PlusIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import { ButtonStyled, NewModal, injectNotificationManager } from "@modrinth/ui";
|
||||
import { ref } from "vue";
|
||||
|
||||
const router = useNativeRouter();
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const name = ref("");
|
||||
const slug = ref("");
|
||||
const description = ref("");
|
||||
const manualSlug = ref(false);
|
||||
const name = ref<string>("");
|
||||
const slug = ref<string>("");
|
||||
const description = ref<string>("");
|
||||
const manualSlug = ref<boolean>(false);
|
||||
const modal = ref<InstanceType<typeof NewModal>>();
|
||||
|
||||
const modal = ref();
|
||||
|
||||
async function createOrganization() {
|
||||
async function createOrganization(): Promise<void> {
|
||||
startLoading();
|
||||
try {
|
||||
const value = {
|
||||
@ -93,16 +94,16 @@ async function createOrganization() {
|
||||
slug: slug.value.trim().replace(/ +/g, ""),
|
||||
};
|
||||
|
||||
const result = await useBaseFetch("organization", {
|
||||
const result: any = await useBaseFetch("organization", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(value),
|
||||
apiVersion: 3,
|
||||
});
|
||||
|
||||
modal.value.hide();
|
||||
modal.value?.hide();
|
||||
|
||||
await router.push(`/organization/${result.slug}`);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
addNotification({
|
||||
title: "An error occurred",
|
||||
@ -112,13 +113,18 @@ async function createOrganization() {
|
||||
}
|
||||
stopLoading();
|
||||
}
|
||||
function show(event) {
|
||||
|
||||
function show(event?: MouseEvent): void {
|
||||
name.value = "";
|
||||
description.value = "";
|
||||
modal.value.show(event);
|
||||
modal.value?.show(event);
|
||||
}
|
||||
|
||||
function updateSlug() {
|
||||
function hide(): void {
|
||||
modal.value?.hide();
|
||||
}
|
||||
|
||||
function updateSlug(): void {
|
||||
if (!manualSlug.value) {
|
||||
slug.value = name.value
|
||||
.trim()
|
||||
@ -129,6 +135,10 @@ function updateSlug() {
|
||||
}
|
||||
}
|
||||
|
||||
function setManualSlug(): void {
|
||||
manualSlug.value = true;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
|
||||
export const useUser = async (force = false) => {
|
||||
const user = useState("user", () => {});
|
||||
|
||||
@ -137,7 +135,8 @@ export const userFollowProject = async (project) => {
|
||||
}
|
||||
};
|
||||
export const resendVerifyEmail = async () => {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
// const { injectNotificationManager } = await import("@modrinth/ui");
|
||||
// const { addNotification } = injectNotificationManager();
|
||||
|
||||
startLoading();
|
||||
try {
|
||||
|
||||
@ -1,19 +1,14 @@
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import type { Organization, Project, Report, User, Version } from "@modrinth/utils";
|
||||
|
||||
// TODO: There needs to be a standardized way to get these types, eg; @modrinth/types generated from api schema. Later problem.
|
||||
type Project = { id: string };
|
||||
type Version = { id: string; project_id: string };
|
||||
type Report = { id: string; item_type: "project" | "user" | "version"; item_id: string };
|
||||
type Thread = { id: string };
|
||||
type User = { id: string };
|
||||
type Organization = { id: string };
|
||||
|
||||
export type NotificationAction = {
|
||||
export type PlatformNotificationAction = {
|
||||
title: string;
|
||||
action_route: [string, string];
|
||||
};
|
||||
|
||||
export type NotificationBody = {
|
||||
export type PlatformNotificationBody = {
|
||||
project_id?: string;
|
||||
version_id?: string;
|
||||
report_id?: string;
|
||||
@ -22,7 +17,7 @@ export type NotificationBody = {
|
||||
organization_id?: string;
|
||||
};
|
||||
|
||||
export type Notification = {
|
||||
export type PlatformNotification = {
|
||||
id: string;
|
||||
user_id: string;
|
||||
type: "project_update" | "team_invite" | "status_change" | "moderator_message";
|
||||
@ -31,10 +26,10 @@ export type Notification = {
|
||||
link: string;
|
||||
read: boolean;
|
||||
created: string;
|
||||
actions: NotificationAction[];
|
||||
body?: NotificationBody;
|
||||
actions: PlatformNotificationAction[];
|
||||
body?: PlatformNotificationBody;
|
||||
extra_data?: Record<string, unknown>;
|
||||
grouped_notifs?: Notification[];
|
||||
grouped_notifs?: PlatformNotification[];
|
||||
};
|
||||
|
||||
async function getBulk<T extends { id: string }>(
|
||||
@ -55,8 +50,8 @@ async function getBulk<T extends { id: string }>(
|
||||
}
|
||||
|
||||
export async function fetchExtraNotificationData(
|
||||
notifications: Notification[],
|
||||
): Promise<Notification[]> {
|
||||
notifications: PlatformNotification[],
|
||||
): Promise<PlatformNotification[]> {
|
||||
const bulk = {
|
||||
projects: [] as string[],
|
||||
reports: [] as string[],
|
||||
@ -133,8 +128,8 @@ export async function fetchExtraNotificationData(
|
||||
return notifications;
|
||||
}
|
||||
|
||||
export function groupNotifications(notifications: Notification[]): Notification[] {
|
||||
const grouped: Notification[] = [];
|
||||
export function groupNotifications(notifications: PlatformNotification[]): PlatformNotification[] {
|
||||
const grouped: PlatformNotification[] = [];
|
||||
for (let i = 0; i < notifications.length; i++) {
|
||||
const current = notifications[i];
|
||||
const next = notifications[i + 1];
|
||||
@ -154,18 +149,18 @@ export function groupNotifications(notifications: Notification[]): Notification[
|
||||
return grouped;
|
||||
}
|
||||
|
||||
function isSimilar(a: Notification, b: Notification | undefined): boolean {
|
||||
function isSimilar(a: PlatformNotification, b: PlatformNotification | undefined): boolean {
|
||||
return !!a?.body?.project_id && a.body!.project_id === b?.body?.project_id;
|
||||
}
|
||||
|
||||
export async function markAsRead(
|
||||
ids: string[],
|
||||
): Promise<(notifications: Notification[]) => Notification[]> {
|
||||
): Promise<(notifications: PlatformNotification[]) => PlatformNotification[]> {
|
||||
try {
|
||||
await useBaseFetch(`notifications?ids=${JSON.stringify([...new Set(ids)])}`, {
|
||||
method: "PATCH",
|
||||
});
|
||||
return (notifications: Notification[]) => {
|
||||
return (notifications: PlatformNotification[]) => {
|
||||
const newNotifs = notifications ?? [];
|
||||
newNotifs.forEach((n) => {
|
||||
if (ids.includes(n.id)) n.read = true;
|
||||
|
||||
@ -1552,11 +1552,15 @@ const collapsedModerationChecklist = useLocalStorage("collapsed-moderation-check
|
||||
watch(
|
||||
showModerationChecklist,
|
||||
(newValue) => {
|
||||
notifications.setNotificationsPanelRightwards(newValue);
|
||||
notifications.setNotificationLocation(newValue ? "left" : "right");
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
notifications.setNotificationLocation("right");
|
||||
});
|
||||
|
||||
if (import.meta.client && history && history.state && history.state.showChecklist) {
|
||||
showModerationChecklist.value = true;
|
||||
}
|
||||
|
||||
@ -1,28 +1,32 @@
|
||||
import { type WebNotification, AbstractWebNotificationManager } from "@modrinth/ui";
|
||||
import { useState } from "#app";
|
||||
import {
|
||||
type WebNotification,
|
||||
type WebNotificationLocation,
|
||||
AbstractWebNotificationManager,
|
||||
} from "@modrinth/ui";
|
||||
|
||||
export class FrontendNotificationManager extends AbstractWebNotificationManager {
|
||||
private readonly state: Ref<WebNotification[]>;
|
||||
private readonly isRightwards: Ref<boolean>;
|
||||
private readonly locationState: Ref<WebNotificationLocation>;
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
this.state = useState<WebNotification[]>("notifications", () => []);
|
||||
this.isRightwards = useState<boolean>("notifications.isRightwards", () => true);
|
||||
this.locationState = useState<WebNotificationLocation>("notifications.location", () => "right");
|
||||
}
|
||||
|
||||
public getNotificationLocation(): WebNotificationLocation {
|
||||
return this.locationState.value;
|
||||
}
|
||||
|
||||
public setNotificationLocation(location: WebNotificationLocation): void {
|
||||
this.locationState.value = location;
|
||||
}
|
||||
|
||||
public getNotifications(): WebNotification[] {
|
||||
return this.state.value;
|
||||
}
|
||||
|
||||
public isNotificationsPanelRightwards(): boolean {
|
||||
return this.isRightwards.value;
|
||||
}
|
||||
|
||||
public setNotificationsPanelRightwards(isRightwards: boolean): void {
|
||||
this.isRightwards.value = isRightwards;
|
||||
}
|
||||
|
||||
protected addNotificationToStorage(notification: WebNotification): void {
|
||||
this.state.value.push(notification);
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div
|
||||
class="vue-notification-group experimental-styles-within"
|
||||
:class="{ 'intercom-present': isIntercomPresent }"
|
||||
:class="{
|
||||
'intercom-present': isIntercomPresent,
|
||||
'location-left': notificationLocation === 'left',
|
||||
'location-right': notificationLocation === 'right',
|
||||
}"
|
||||
>
|
||||
<transition-group name="notifs">
|
||||
<div
|
||||
@ -72,20 +76,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { ButtonStyled, injectNotificationManager, type WebNotification } from '@modrinth/ui'
|
||||
import {
|
||||
XCircleIcon,
|
||||
CheckCircleIcon,
|
||||
CheckIcon,
|
||||
CopyIcon,
|
||||
InfoIcon,
|
||||
IssuesIcon,
|
||||
XCircleIcon,
|
||||
XIcon,
|
||||
CopyIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ButtonStyled, injectNotificationManager, type WebNotification } from '@modrinth/ui'
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
|
||||
const notificationManager = injectNotificationManager()
|
||||
const notifications = computed<WebNotification[]>(() => notificationManager.getNotifications())
|
||||
const notificationLocation = computed(() => notificationManager.getNotificationLocation())
|
||||
|
||||
const isIntercomPresent = ref<boolean>(false)
|
||||
const copied = ref<Record<string, boolean>>({})
|
||||
@ -134,15 +139,31 @@ onMounted(() => {
|
||||
<style lang="scss" scoped>
|
||||
.vue-notification-group {
|
||||
position: fixed;
|
||||
right: 1.5rem;
|
||||
bottom: 1.5rem;
|
||||
z-index: 200;
|
||||
width: 450px;
|
||||
|
||||
&.location-right {
|
||||
right: 1.5rem;
|
||||
}
|
||||
|
||||
&.location-left {
|
||||
left: 1.5rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
width: calc(100% - 0.75rem * 2);
|
||||
right: 0.75rem;
|
||||
bottom: 0.75rem;
|
||||
|
||||
&.location-right {
|
||||
right: 0.75rem;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
&.location-left {
|
||||
left: 0.75rem;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.intercom-present {
|
||||
@ -184,6 +205,12 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.notifs-leave-to {
|
||||
transform: translateX(100%) scale(0.8);
|
||||
.location-right & {
|
||||
transform: translateX(100%) scale(0.8);
|
||||
}
|
||||
|
||||
.location-left & {
|
||||
transform: translateX(-100%) scale(0.8);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -10,17 +10,21 @@ export interface WebNotification {
|
||||
timer?: NodeJS.Timeout
|
||||
}
|
||||
|
||||
export type WebNotificationLocation = 'left' | 'right'
|
||||
|
||||
export abstract class AbstractWebNotificationManager {
|
||||
protected readonly AUTO_DISMISS_DELAY_MS = 30 * 1000
|
||||
|
||||
abstract getNotifications(): WebNotification[]
|
||||
abstract getNotificationLocation(): WebNotificationLocation
|
||||
abstract setNotificationLocation(location: WebNotificationLocation): void
|
||||
|
||||
protected abstract addNotificationToStorage(notification: WebNotification): void
|
||||
protected abstract removeNotificationFromStorage(id: string | number): void
|
||||
protected abstract removeNotificationFromStorageByIndex(index: number): void
|
||||
protected abstract clearAllNotificationsFromStorage(): void
|
||||
|
||||
addNotification(notification: Partial<WebNotification>): void {
|
||||
addNotification = (notification: Partial<WebNotification>): void => {
|
||||
const existingNotif = this.findExistingNotification(notification)
|
||||
|
||||
if (existingNotif) {
|
||||
@ -34,7 +38,7 @@ export abstract class AbstractWebNotificationManager {
|
||||
this.addNotificationToStorage(newNotification)
|
||||
}
|
||||
|
||||
removeNotification(id: string | number): void {
|
||||
removeNotification = (id: string | number): void => {
|
||||
const notifications = this.getNotifications()
|
||||
const notification = notifications.find((n) => n.id === id)
|
||||
|
||||
@ -44,7 +48,7 @@ export abstract class AbstractWebNotificationManager {
|
||||
}
|
||||
}
|
||||
|
||||
removeNotificationByIndex(index: number): void {
|
||||
removeNotificationByIndex = (index: number): void => {
|
||||
const notifications = this.getNotifications()
|
||||
|
||||
if (index >= 0 && index < notifications.length) {
|
||||
@ -54,7 +58,7 @@ export abstract class AbstractWebNotificationManager {
|
||||
}
|
||||
}
|
||||
|
||||
clearAllNotifications(): void {
|
||||
clearAllNotifications = (): void => {
|
||||
const notifications = this.getNotifications()
|
||||
notifications.forEach((notification) => {
|
||||
this.clearNotificationTimer(notification)
|
||||
@ -62,7 +66,7 @@ export abstract class AbstractWebNotificationManager {
|
||||
this.clearAllNotificationsFromStorage()
|
||||
}
|
||||
|
||||
setNotificationTimer(notification: WebNotification): void {
|
||||
setNotificationTimer = (notification: WebNotification): void => {
|
||||
if (!notification) return
|
||||
|
||||
this.clearNotificationTimer(notification)
|
||||
@ -72,7 +76,7 @@ export abstract class AbstractWebNotificationManager {
|
||||
}, this.AUTO_DISMISS_DELAY_MS)
|
||||
}
|
||||
|
||||
stopNotificationTimer(notification: WebNotification): void {
|
||||
stopNotificationTimer = (notification: WebNotification): void => {
|
||||
this.clearNotificationTimer(notification)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user