Platform page UX improvements (#3009)
* chore: initial fixes from app redesign merge Signed-off-by: Evan Song <theevansong@gmail.com> * fix: ccpa hydration error Signed-off-by: Evan Song <theevansong@gmail.com> * fix: migrate tailwind to esm Signed-off-by: Evan Song <theevansong@gmail.com> * feat: default platform selection to current mc version Signed-off-by: Evan Song <theevansong@gmail.com> * fix: navigating and installing content Signed-off-by: Evan Song <theevansong@gmail.com> * chore: respect sentence case Signed-off-by: Evan Song <theevansong@gmail.com> * fix: match new page padding Signed-off-by: Evan Song <theevansong@gmail.com> * feat: allow user to erase all data when installing from modpack Signed-off-by: Evan Song <theevansong@gmail.com> * chore: hide hide installed content check if modpack search Signed-off-by: Evan Song <theevansong@gmail.com> * chore: wording Signed-off-by: Evan Song <theevansong@gmail.com> * chore: make erase data toggle more prominent Signed-off-by: Evan Song <theevansong@gmail.com> --------- Signed-off-by: Evan Song <theevansong@gmail.com>
This commit is contained in:
parent
1f060b8513
commit
e86c9df39d
@ -21,108 +21,110 @@
|
|||||||
within the last twelve (12) months:
|
within the last twelve (12) months:
|
||||||
</p>
|
</p>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tbody>
|
||||||
<th>Category</th>
|
<tr>
|
||||||
<th>Examples</th>
|
<th>Category</th>
|
||||||
<th>Collected</th>
|
<th>Examples</th>
|
||||||
</tr>
|
<th>Collected</th>
|
||||||
<tr>
|
</tr>
|
||||||
<td>A. Identifiers.</td>
|
<tr>
|
||||||
<td>
|
<td>A. Identifiers.</td>
|
||||||
A real name, alias, postal address, unique personal identifier, online identifier,
|
<td>
|
||||||
Internet Protocol address, email address, account name, Social Security number, driver's
|
A real name, alias, postal address, unique personal identifier, online identifier,
|
||||||
license number, passport number, or other similar identifiers.
|
Internet Protocol address, email address, account name, Social Security number, driver's
|
||||||
</td>
|
license number, passport number, or other similar identifiers.
|
||||||
<td>YES</td>
|
</td>
|
||||||
</tr>
|
<td>YES</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
B. Personal information categories listed in the California Customer Records statute (Cal.
|
<td>
|
||||||
Civ. Code § 1798.80(e)).
|
B. Personal information categories listed in the California Customer Records statute
|
||||||
</td>
|
(Cal. Civ. Code § 1798.80(e)).
|
||||||
<td>
|
</td>
|
||||||
A name, signature, Social Security number, physical characteristics or description,
|
<td>
|
||||||
address, telephone number, passport number, driver's license or state identification card
|
A name, signature, Social Security number, physical characteristics or description,
|
||||||
number, insurance policy number, education, employment, employment history, bank account
|
address, telephone number, passport number, driver's license or state identification
|
||||||
number, credit card number, debit card number, or any other financial information, medical
|
card number, insurance policy number, education, employment, employment history, bank
|
||||||
information, or health insurance information. <br /><br />
|
account number, credit card number, debit card number, or any other financial
|
||||||
Some personal information included in this category may overlap with other categories.
|
information, medical information, or health insurance information. <br /><br />
|
||||||
</td>
|
Some personal information included in this category may overlap with other categories.
|
||||||
<td>NO</td>
|
</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>C. Protected classification characteristics.</td>
|
<tr>
|
||||||
<td>
|
<td>C. Protected classification characteristics.</td>
|
||||||
Age (40 years or older), race, color, ancestry, national origin, citizenship, religion or
|
<td>
|
||||||
creed, marital status, medical condition, physical or mental disability, sex (including
|
Age (40 years or older), race, color, ancestry, national origin, citizenship, religion
|
||||||
gender, gender identity, gender expression, pregnancy or childbirth and related medical
|
or creed, marital status, medical condition, physical or mental disability, sex
|
||||||
conditions), sexual orientation, veteran or military status, genetic information
|
(including gender, gender identity, gender expression, pregnancy or childbirth and
|
||||||
(including familial genetic information).
|
related medical conditions), sexual orientation, veteran or military status, genetic
|
||||||
</td>
|
information (including familial genetic information).
|
||||||
<td>NO</td>
|
</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>D. Commercial information.</td>
|
<tr>
|
||||||
<td>
|
<td>D. Commercial information.</td>
|
||||||
Records of personal property, products or services purchased, obtained, or considered, or
|
<td>
|
||||||
other purchasing or consuming histories or tendencies.
|
Records of personal property, products or services purchased, obtained, or considered,
|
||||||
</td>
|
or other purchasing or consuming histories or tendencies.
|
||||||
<td>NO</td>
|
</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>E. Biometric information.</td>
|
<tr>
|
||||||
<td>
|
<td>E. Biometric information.</td>
|
||||||
Genetic, physiological, behavioral, and biological characteristics, or activity patterns
|
<td>
|
||||||
used to extract a template or other identifier or identifying information, such as,
|
Genetic, physiological, behavioral, and biological characteristics, or activity patterns
|
||||||
fingerprints, faceprints, and voiceprints, iris or retina scans, keystroke, gait, or other
|
used to extract a template or other identifier or identifying information, such as,
|
||||||
physical patterns, and sleep, health, or exercise data.
|
fingerprints, faceprints, and voiceprints, iris or retina scans, keystroke, gait, or
|
||||||
</td>
|
other physical patterns, and sleep, health, or exercise data.
|
||||||
<td>NO</td>
|
</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>F. Internet or other similar network activity.</td>
|
<tr>
|
||||||
<td>
|
<td>F. Internet or other similar network activity.</td>
|
||||||
Browsing history, search history, information on a consumer's interaction with a website,
|
<td>
|
||||||
application, or advertisement.
|
Browsing history, search history, information on a consumer's interaction with a
|
||||||
</td>
|
website, application, or advertisement.
|
||||||
<td>YES</td>
|
</td>
|
||||||
</tr>
|
<td>YES</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>G. Geolocation data.</td>
|
<tr>
|
||||||
<td>Physical location or movements.</td>
|
<td>G. Geolocation data.</td>
|
||||||
<td>YES</td>
|
<td>Physical location or movements.</td>
|
||||||
</tr>
|
<td>YES</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>H. Sensory data.</td>
|
<tr>
|
||||||
<td>Audio, electronic, visual, thermal, olfactory, or similar information.</td>
|
<td>H. Sensory data.</td>
|
||||||
<td>NO</td>
|
<td>Audio, electronic, visual, thermal, olfactory, or similar information.</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>I. Professional or employment-related information.</td>
|
<tr>
|
||||||
<td>Current or past job history or performance evaluations.</td>
|
<td>I. Professional or employment-related information.</td>
|
||||||
<td>NO</td>
|
<td>Current or past job history or performance evaluations.</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
J. Non-public education information (per the Family Educational Rights and Privacy Act (20
|
<td>
|
||||||
U.S.C. Section 1232g, 34 C.F.R. Part 99)).
|
J. Non-public education information (per the Family Educational Rights and Privacy Act
|
||||||
</td>
|
(20 U.S.C. Section 1232g, 34 C.F.R. Part 99)).
|
||||||
<td>
|
</td>
|
||||||
Education records directly related to a student maintained by an educational institution
|
<td>
|
||||||
or party acting on its behalf, such as grades, transcripts, class lists, student
|
Education records directly related to a student maintained by an educational institution
|
||||||
schedules, student identification codes, student financial information, or student
|
or party acting on its behalf, such as grades, transcripts, class lists, student
|
||||||
disciplinary records.
|
schedules, student identification codes, student financial information, or student
|
||||||
</td>
|
disciplinary records.
|
||||||
<td>NO</td>
|
</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>K. Inferences drawn from other personal information.</td>
|
<tr>
|
||||||
<td>
|
<td>K. Inferences drawn from other personal information.</td>
|
||||||
Profile reflecting a person's preferences, characteristics, psychological trends,
|
<td>
|
||||||
predispositions, behavior, attitudes, intelligence, abilities, and aptitudes.
|
Profile reflecting a person's preferences, characteristics, psychological trends,
|
||||||
</td>
|
predispositions, behavior, attitudes, intelligence, abilities, and aptitudes.
|
||||||
<td>NO</td>
|
</td>
|
||||||
</tr>
|
<td>NO</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p>Personal information does not include:</p>
|
<p>Personal information does not include:</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@ -84,7 +84,26 @@
|
|||||||
</button>
|
</button>
|
||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="server" class="rounded-2xl bg-bg-raised p-4">
|
<div v-if="server && projectType.id === 'modpack'" class="rounded-2xl bg-bg-raised">
|
||||||
|
<div class="flex flex-row items-center gap-2 px-6 py-4 text-contrast">
|
||||||
|
<h3 class="m-0 text-lg">Options</h3>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row items-center justify-between gap-2 px-6">
|
||||||
|
<label for="erase-data-on-install"> Erase all data on install </label>
|
||||||
|
<input
|
||||||
|
id="erase-data-on-install"
|
||||||
|
v-model="eraseDataOnInstall"
|
||||||
|
label="Erase all data on install"
|
||||||
|
class="switch stylized-toggle flex-none"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="px-6 py-4 text-sm">
|
||||||
|
If enabled, existing mods, worlds, and configurations, will be deleted before installing
|
||||||
|
the selected modpack.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="server && projectType.id !== 'modpack'" class="rounded-2xl bg-bg-raised p-4">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
v-model="serverHideInstalled"
|
v-model="serverHideInstalled"
|
||||||
label="Hide installed content"
|
label="Hide installed content"
|
||||||
@ -238,7 +257,7 @@
|
|||||||
<button
|
<button
|
||||||
v-if="
|
v-if="
|
||||||
result.installed ||
|
result.installed ||
|
||||||
server.mods.data.find((x) => x.project_id === result.project_id) ||
|
server.content.data.find((x) => x.project_id === result.project_id) ||
|
||||||
server.general?.project?.id === result.project_id
|
server.general?.project?.id === result.project_id
|
||||||
"
|
"
|
||||||
disabled
|
disabled
|
||||||
@ -328,6 +347,7 @@ const projectTypes = computed(() => [projectType.value.id]);
|
|||||||
|
|
||||||
const server = ref();
|
const server = ref();
|
||||||
const serverHideInstalled = ref(false);
|
const serverHideInstalled = ref(false);
|
||||||
|
const eraseDataOnInstall = ref(false);
|
||||||
|
|
||||||
const PERSISTENT_QUERY_PARAMS = ["sid", "shi"];
|
const PERSISTENT_QUERY_PARAMS = ["sid", "shi"];
|
||||||
|
|
||||||
@ -342,7 +362,7 @@ async function updateServerContext() {
|
|||||||
if (!auth.value.user) {
|
if (!auth.value.user) {
|
||||||
router.push("/auth/sign-in?redirect=" + encodeURIComponent(route.fullPath));
|
router.push("/auth/sign-in?redirect=" + encodeURIComponent(route.fullPath));
|
||||||
} else if (route.query.sid !== null) {
|
} else if (route.query.sid !== null) {
|
||||||
server.value = await usePyroServer(route.query.sid, ["general", "mods"]);
|
server.value = await usePyroServer(route.query.sid, ["general", "content"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +402,7 @@ const serverFilters = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serverHideInstalled.value) {
|
if (serverHideInstalled.value) {
|
||||||
const installedMods = server.value.mods?.data
|
const installedMods = server.value.content?.data
|
||||||
.filter((x) => x.project_id)
|
.filter((x) => x.project_id)
|
||||||
.map((x) => x.project_id);
|
.map((x) => x.project_id);
|
||||||
|
|
||||||
@ -461,7 +481,14 @@ async function serverInstall(project) {
|
|||||||
) ?? versions[0];
|
) ?? versions[0];
|
||||||
|
|
||||||
if (projectType.value.id === "modpack") {
|
if (projectType.value.id === "modpack") {
|
||||||
await server.value.general?.reinstall(route.query.sid, false, project.project_id, version.id);
|
await server.value.general?.reinstall(
|
||||||
|
route.query.sid,
|
||||||
|
false,
|
||||||
|
project.project_id,
|
||||||
|
version.id,
|
||||||
|
undefined,
|
||||||
|
eraseDataOnInstall.value,
|
||||||
|
);
|
||||||
project.installed = true;
|
project.installed = true;
|
||||||
navigateTo(`/servers/manage/${route.query.sid}/options/loader`);
|
navigateTo(`/servers/manage/${route.query.sid}/options/loader`);
|
||||||
} else if (projectType.value.id === "mod") {
|
} else if (projectType.value.id === "mod") {
|
||||||
@ -817,4 +844,8 @@ useSeoMeta({
|
|||||||
mask-image: linear-gradient(to bottom, black, transparent);
|
mask-image: linear-gradient(to bottom, black, transparent);
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stylized-toggle:checked::after {
|
||||||
|
background: var(--color-accent-contrast) !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -86,10 +86,12 @@
|
|||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- SERVER START -->
|
||||||
<div
|
<div
|
||||||
v-else-if="serverData"
|
v-else-if="serverData"
|
||||||
data-pyro-server-manager-root
|
data-pyro-server-manager-root
|
||||||
class="experimental-styles-within mobile-blurred-servericon relative mx-auto box-border flex min-h-screen w-full min-w-0 max-w-[1280px] flex-col gap-6 px-3 transition-all duration-300"
|
class="experimental-styles-within mobile-blurred-servericon relative mx-auto box-border flex min-h-screen w-full min-w-0 max-w-[1280px] flex-col gap-6 px-6 transition-all duration-300"
|
||||||
:style="{
|
:style="{
|
||||||
'--server-bg-image': serverData.image
|
'--server-bg-image': serverData.image
|
||||||
? `url(${serverData.image})`
|
? `url(${serverData.image})`
|
||||||
@ -302,6 +304,7 @@ import {
|
|||||||
import DOMPurify from "dompurify";
|
import DOMPurify from "dompurify";
|
||||||
import { ButtonStyled } from "@modrinth/ui";
|
import { ButtonStyled } from "@modrinth/ui";
|
||||||
import { Intercom, shutdown } from "@intercom/messenger-js-sdk";
|
import { Intercom, shutdown } from "@intercom/messenger-js-sdk";
|
||||||
|
import { reloadNuxtApp } from "#app";
|
||||||
import type { ServerState, Stats, WSEvent, WSInstallationResultEvent } from "~/types/servers";
|
import type { ServerState, Stats, WSEvent, WSInstallationResultEvent } from "~/types/servers";
|
||||||
import { usePyroConsole } from "~/store/console.ts";
|
import { usePyroConsole } from "~/store/console.ts";
|
||||||
|
|
||||||
|
|||||||
@ -237,7 +237,7 @@ import { ref, computed } from "vue";
|
|||||||
import type { Server } from "~/composables/pyroServers";
|
import type { Server } from "~/composables/pyroServers";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
server: Server<["general", "mods", "backups", "network", "startup", "ws", "fs"]>;
|
server: Server<["general", "content", "backups", "network", "startup", "ws", "fs"]>;
|
||||||
isServerRunning: boolean;
|
isServerRunning: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|||||||
@ -102,10 +102,10 @@
|
|||||||
<ButtonStyled v-if="hasMods" color="brand" type="outlined">
|
<ButtonStyled v-if="hasMods" color="brand" type="outlined">
|
||||||
<nuxt-link
|
<nuxt-link
|
||||||
class="w-full text-nowrap sm:w-fit"
|
class="w-full text-nowrap sm:w-fit"
|
||||||
:to="`/${type}s?sid=${props.server.serverId}`"
|
:to="`/${type.toLocaleLowerCase()}s?sid=${props.server.serverId}`"
|
||||||
>
|
>
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
Add {{ type }}
|
Add {{ type.toLocaleLowerCase() }}
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
</div>
|
</div>
|
||||||
@ -241,9 +241,9 @@
|
|||||||
<p class="m-0 font-bold text-contrast">No {{ type }}s found!</p>
|
<p class="m-0 font-bold text-contrast">No {{ type }}s found!</p>
|
||||||
<p class="m-0">Add some {{ type }}s to your server to manage them here.</p>
|
<p class="m-0">Add some {{ type }}s to your server to manage them here.</p>
|
||||||
<ButtonStyled color="brand">
|
<ButtonStyled color="brand">
|
||||||
<NuxtLink :to="`/${type}s?sid=${props.server.serverId}`">
|
<NuxtLink :to="`/${type.toLocaleLowerCase()}s?sid=${props.server.serverId}`">
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
Add {{ type }}
|
Add {{ type.toLocaleLowerCase() }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
</div>
|
</div>
|
||||||
@ -299,7 +299,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const type = computed(() => {
|
const type = computed(() => {
|
||||||
const loader = props.server.general?.loader?.toLowerCase();
|
const loader = props.server.general?.loader?.toLowerCase();
|
||||||
return loader === "paper" || loader === "purpur" ? "plugin" : "mod";
|
return loader === "paper" || loader === "purpur" ? "Plugin" : "Mod";
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Mod {
|
interface Mod {
|
||||||
@ -460,7 +460,10 @@ async function removeMod(mod: Mod) {
|
|||||||
mod.changing = true;
|
mod.changing = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await props.server.content?.remove(type.value, `/${type.value}s/${mod.filename}`);
|
await props.server.content?.remove(
|
||||||
|
type.value as "Mod" | "Plugin",
|
||||||
|
`/${type.value.toLowerCase()}s/${mod.filename}`,
|
||||||
|
);
|
||||||
await props.server.refresh(["general", "content"]);
|
await props.server.refresh(["general", "content"]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error removing mod:", error);
|
console.error("Error removing mod:", error);
|
||||||
|
|||||||
@ -198,7 +198,7 @@ type ServerProps = {
|
|||||||
exit_code?: number;
|
exit_code?: number;
|
||||||
};
|
};
|
||||||
isServerRunning: boolean;
|
isServerRunning: boolean;
|
||||||
server: Server<["general", "mods", "backups", "network", "startup", "ws", "fs"]>;
|
server: Server<["general", "content", "backups", "network", "startup", "ws", "fs"]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const props = defineProps<ServerProps>();
|
const props = defineProps<ServerProps>();
|
||||||
|
|||||||
@ -703,7 +703,7 @@ watch(selectedMCVersion, async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onShow = () => {
|
const onShow = () => {
|
||||||
selectedMCVersion.value = "";
|
selectedMCVersion.value = props.server.general?.mc_version || "";
|
||||||
selectedLoaderVersion.value = "";
|
selectedLoaderVersion.value = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
const config = {
|
||||||
content: [
|
content: [
|
||||||
"./src/components/**/*.{js,vue,ts}",
|
"./src/components/**/*.{js,vue,ts}",
|
||||||
"./src/layouts/**/*.vue",
|
"./src/layouts/**/*.vue",
|
||||||
@ -152,3 +152,5 @@ module.exports = {
|
|||||||
preflight: false,
|
preflight: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user