Merge branch 'fix-settings-menu' into 'master'

Fix settings menu

See merge request framasoft/mobilizon!494
This commit is contained in:
Thomas Citharel 2020-06-25 12:51:09 +02:00
commit 97c153ada3
33 changed files with 2911 additions and 2830 deletions

View file

@ -39,6 +39,7 @@ lint:
- cd js
- yarn install
#- yarn run lint || export EXITVALUE=1
- yarn run prettier -c .
- yarn run build
- cd ../
- exit $EXITVALUE

View file

@ -50,10 +50,12 @@ module.exports = {
ignorePatterns: ["src/typings/*.d.ts", "vue.config.js"],
overrides: [{
overrides: [
{
files: ["**/__tests__/*.{j,t}s?(x)", "**/tests/unit/**/*.spec.{j,t}s?(x)"],
env: {
mocha: true,
},
}],
},
],
};

View file

@ -1,6 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
@ -11,12 +10,13 @@
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong>
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View file

@ -1,6 +1,6 @@
a {
text-decoration: underline;
text-decoration-color: #ED8D07;
text-decoration-color: #ed8d07;
text-decoration-thickness: 2px;
&.navbar-item,
@ -17,6 +17,10 @@ a {
}
}
nav.breadcrumb ul li a {
text-decoration: none;
}
input.input {
border-color: $input-border-color !important;
}

View file

@ -1,24 +1,25 @@
<template>
<li class="setting-menu-item" :class="{ active: isActive }">
<router-link v-if="menuItem.to" :to="menuItem.to">
<span>{{ menuItem.title }}</span>
<router-link v-if="to" :to="to">
<span>{{ title }}</span>
</router-link>
<span v-else>{{ menuItem.title }}</span>
<span v-else>{{ title }}</span>
</li>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { ISettingMenuSection } from "@/types/setting-menu.model";
import { Route } from "vue-router";
@Component
export default class SettingMenuItem extends Vue {
@Prop({ required: true, type: Object }) menuItem!: ISettingMenuSection;
@Prop({ required: false, type: String }) title!: string;
@Prop({ required: true, type: Object }) to!: Route;
get isActive() {
if (!this.menuItem.to) return false;
if (this.menuItem.to.name === this.$route.name) {
if (this.menuItem.to.params) {
return this.menuItem.to.params.identityName === this.$route.params.identityName;
if (!this.to) return false;
if (this.to.name === this.$route.name) {
if (this.to.params) {
return this.to.params.identityName === this.$route.params.identityName;
}
return true;
}

View file

@ -1,28 +1,36 @@
<template>
<li :class="{ active: sectionActive }">
<router-link v-if="menuSection.to" :to="menuSection.to">{{ menuSection.title }}</router-link>
<b v-else>{{ menuSection.title }}</b>
<router-link v-if="to" :to="to">{{ title }}</router-link>
<b v-else>{{ title }}</b>
<ul>
<setting-menu-item :menu-item="item" v-for="item in menuSection.items" :key="item.title" />
<slot></slot>
</ul>
</li>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { ISettingMenuSection } from "@/types/setting-menu.model";
import SettingMenuItem from "@/components/Settings/SettingMenuItem.vue";
import { Route } from "vue-router";
@Component({
components: { SettingMenuItem },
})
export default class SettingMenuSection extends Vue {
@Prop({ required: true, type: Object }) menuSection!: ISettingMenuSection;
@Prop({ required: false, type: String }) title!: string;
@Prop({ required: true, type: Object }) to!: Route;
get sectionActive(): boolean | undefined {
return (
this.menuSection.items &&
this.menuSection.items.some(({ to }) => to && to.name === this.$route.name)
get sectionActive() {
if (this.$slots.default) {
return this.$slots.default.some(
({
componentOptions: {
// @ts-ignore
propsData: { to },
},
}) => to && to.name === this.$route.name
);
}
return false;
}
}
</script>

View file

@ -1,27 +1,88 @@
<template>
<aside>
<ul>
<SettingMenuSection
v-for="section in menuValue"
:key="section.title"
:menu-section="section"
<SettingMenuSection :title="$t('Account')" :to="{ name: RouteName.ACCOUNT_SETTINGS }">
<SettingMenuItem
:title="this.$t('General')"
:to="{ name: RouteName.ACCOUNT_SETTINGS_GENERAL }"
/>
<SettingMenuItem :title="$t('Preferences')" :to="{ name: RouteName.PREFERENCES }" />
<SettingMenuItem
:title="this.$t('Email notifications')"
:to="{ name: RouteName.NOTIFICATIONS }"
/>
</SettingMenuSection>
<SettingMenuSection :title="$t('Profiles')" :to="{ name: RouteName.IDENTITIES }">
<SettingMenuItem
v-for="profile in identities"
:key="profile.preferredUsername"
:title="profile.preferredUsername"
:to="{
name: RouteName.UPDATE_IDENTITY,
params: { identityName: profile.preferredUsername },
}"
/>
<SettingMenuItem :title="$t('New profile')" :to="{ name: RouteName.CREATE_IDENTITY }" />
</SettingMenuSection>
<SettingMenuSection
v-if="
[ICurrentUserRole.MODERATOR, ICurrentUserRole.ADMINISTRATOR].includes(
this.currentUser.role
)
"
:title="$t('Moderation')"
:to="{ name: RouteName.MODERATION }"
>
<SettingMenuItem :title="$t('Reports')" :to="{ name: RouteName.REPORTS }" />
<SettingMenuItem :title="$t('Moderation log')" :to="{ name: RouteName.REPORT_LOGS }" />
<SettingMenuItem :title="$t('Users')" :to="{ name: RouteName.USERS }" />
<SettingMenuItem :title="$t('Profiles')" :to="{ name: RouteName.PROFILES }" />
</SettingMenuSection>
<SettingMenuSection
v-if="this.currentUser.role == ICurrentUserRole.ADMINISTRATOR"
:title="$t('Admin')"
:to="{ name: RouteName.ADMIN }"
>
<SettingMenuItem :title="$t('Dashboard')" :to="{ name: RouteName.ADMIN_DASHBOARD }" />
<SettingMenuItem
:title="$t('Instance settings')"
:to="{ name: RouteName.ADMIN_SETTINGS }"
/>
<SettingMenuItem :title="$t('Federation')" :to="{ name: RouteName.RELAYS }" />
</SettingMenuSection>
</ul>
</aside>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import SettingMenuSection from "@/components/Settings/SettingMenuSection.vue";
import { ISettingMenuSection } from "@/types/setting-menu.model";
import SettingMenuSection from "./SettingMenuSection.vue";
import SettingMenuItem from "./SettingMenuItem.vue";
import { IDENTITIES } from "../../graphql/actor";
import { IPerson, Person } from "../../types/actor";
import { CURRENT_USER_CLIENT } from "../../graphql/user";
import { ICurrentUser, ICurrentUserRole } from "../../types/current-user.model";
import RouteName from "../../router/name";
@Component({
components: { SettingMenuSection },
components: { SettingMenuSection, SettingMenuItem },
apollo: {
identities: {
query: IDENTITIES,
update: (data) => data.identities.map((identity: IPerson) => new Person(identity)),
},
currentUser: CURRENT_USER_CLIENT,
},
})
export default class SettingsMenu extends Vue {
@Prop({ required: true, type: Array }) menu!: ISettingMenuSection[];
profiles = [];
get menuValue() {
return this.menu;
}
currentUser!: ICurrentUser;
identities!: IPerson[];
ICurrentUserRole = ICurrentUserRole;
RouteName = RouteName;
}
</script>
<style lang="scss" scoped>

View file

@ -106,6 +106,7 @@ export const USER_SETTINGS_FRAGMENT = gql`
export const USER_SETTINGS = gql`
query UserSetting {
loggedUser {
id
locale
settings {
...UserSettingFragment

View file

@ -695,5 +695,6 @@
"contact uninformed": "contact uninformed",
"Can be an email or a link, or just plain text.": "Can be an email or a link, or just plain text.",
"No profiles found": "No profiles found",
"URL copied to clipboard": "URL copied to clipboard"
"URL copied to clipboard": "URL copied to clipboard",
"Report #{reportNumber}": "Report #{reportNumber}"
}

View file

@ -695,5 +695,6 @@
"A place for your code of conduct, rules or guidelines. You can use HTML tags.": "Une section appropriée pour votre code de conduite, règles ou lignes directrices. Vous pouvez utiliser des balises HTML.",
"contact uninformed": "contact non renseigné",
"Can be an email or a link, or just plain text.": "Peut être une adresse email ou bien un lien, ou alors du simple texte brut.",
"URL copied to clipboard": "URL copiée dans le presse-papiers"
"URL copied to clipboard": "URL copiée dans le presse-papiers",
"Report #{reportNumber}": "Signalement #{reportNumber}"
}

View file

@ -1,8 +0,0 @@
import { Route } from "vue-router";
export interface ISettingMenuSection {
title: string;
to: Route;
items?: ISettingMenuSection[];
parents?: ISettingMenuSection[];
}

View file

@ -7,19 +7,19 @@ $violet: #424056;
/**
* Text body, paragraphs
*/
$violet-1: #3A384C;
$violet-1: #3a384c;
$violet-2: #474467;
/**
* Titles, dark borders, buttons
*/
$violet-3: #3C376E;
$violet-3: #3c376e;
/**
* Borders
*/
$borders: #D7D6DE;
$backgrounds: #ECEBF2;
$borders: #d7d6de;
$backgrounds: #ecebf2;
/**
* Text
@ -29,15 +29,15 @@ $purple-1: #757199;
/**
* Background
*/
$purple-2: #CDCAEA;
$purple-3: #E6E4F4;
$purple-2: #cdcaea;
$purple-3: #e6e4f4;
$orange-2: #ED8D07;
$orange-3: #D35204;
$orange-2: #ed8d07;
$orange-3: #d35204;
$yellow-1: #FFD599;
$yellow-2: #FFF1DE;
$yellow-3: #FBD5CB;
$yellow-1: #ffd599;
$yellow-2: #fff1de;
$yellow-3: #fbd5cb;
$yellow-4: #f7ba30;
$primary: $bleuvert;
@ -47,36 +47,45 @@ $secondary-invert: findColorInvert($secondary);
$background-color: $violet-2;
$success: #0D8758;
$success: #0d8758;
$success-invert: findColorInvert($success);
$info: #36bcd4;
$info-invert: findColorInvert($info);
$danger: #FF2E54;
$danger: #ff2e54;
$danger-invert: findColorInvert($danger);
$link: $primary;
$link-invert: $primary-invert;
$text: $violet-1;
$colors: map-merge($colors,
("primary": ($primary,
$colors: map-merge(
$colors,
(
"primary": (
$primary,
$primary-invert,
),
"secondary": ($secondary,
"secondary": (
$secondary,
$secondary-invert,
),
"success": ($success,
"success": (
$success,
$success-invert,
),
"info": ($info,
"info": (
$info,
$info-invert,
),
"danger": ($danger,
"danger": (
$danger,
$danger-invert,
),
"link": ($link,
"link": (
$link,
$link-invert,
),
));
)
);
// Navbar
$navbar-background-color: $secondary;
@ -96,11 +105,7 @@ main>.container {
}
$title-color: #3c376e;
$title-family: "Liberation Sans",
"Helvetica Neue",
Roboto,
Helvetica,
Arial,
$title-family: "Liberation Sans", "Helvetica Neue", Roboto, Helvetica, Arial,
serif;
$title-weight: 700;
$title-size: 40px;
@ -108,11 +113,7 @@ $title-sub-size: 45px;
$title-sup-size: 30px;
$subtitle-color: #3a384c;
$subtitle-family: "Liberation Sans",
"Helvetica Neue",
Roboto,
Helvetica,
Arial,
$subtitle-family: "Liberation Sans", "Helvetica Neue", Roboto, Helvetica, Arial,
serif;
$subtitle-weight: 400;
$subtitle-size: 32px;

View file

@ -1,4 +1,26 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.IDENTITIES }">{{ $t("Profiles") }}</router-link>
</li>
<li class="is-active" v-if="isUpdate && identity">
<router-link
:to="{
name: RouteName.UPDATE_IDENTITY,
params: { identityName: identity.preferredUsername },
}"
>{{ identity.name }}</router-link
>
</li>
<li class="is-active" v-else>
<router-link :to="{ name: RouteName.CREATE_IDENTITY }">{{
$t("New profile")
}}</router-link>
</li>
</ul>
</nav>
<div class="root" v-if="identity">
<h1 class="title">
<span v-if="isUpdate">{{ identity.displayName() }}</span>
@ -55,7 +77,9 @@
<b-field class="submit">
<div class="control">
<button type="button" class="button is-primary" @click="submit()">{{ $t("Save") }}</button>
<button type="button" class="button is-primary" @click="submit()">
{{ $t("Save") }}
</button>
</div>
</b-field>
@ -63,6 +87,7 @@
<span @click="openDeleteIdentityConfirmation()">{{ $t("Delete this identity") }}</span>
</div>
</div>
</div>
</template>
<style scoped type="scss">
@ -148,6 +173,8 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
private currentActor: IPerson | null = null;
RouteName = RouteName;
get message() {
if (this.isUpdate) return null;
return this.$t("Only alphanumeric characters and underscores are supported.");

View file

@ -1,4 +1,15 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{ $t("Admin") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.ADMIN_DASHBOARD }">{{ $t("Dashboard") }}</router-link>
</li>
</ul>
</nav>
<section>
<h1 class="title">{{ $t("Administration") }}</h1>
<div class="tile is-ancestor" v-if="dashboard">
@ -48,6 +59,7 @@
</div>
</div>
</section>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

View file

@ -1,4 +1,23 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{ $t("Admin") }}</router-link>
</li>
<li>
<router-link :to="{ name: RouteName.RELAYS }">{{ $t("Federation") }}</router-link>
</li>
<li class="is-active" v-if="$route.name == RouteName.RELAY_FOLLOWINGS">
<router-link :to="{ name: RouteName.RELAY_FOLLOWINGS }">{{
$t("Followings")
}}</router-link>
</li>
<li class="is-active" v-if="$route.name == RouteName.RELAY_FOLLOWERS">
<router-link :to="{ name: RouteName.RELAY_FOLLOWERS }">{{ $t("Followers") }}</router-link>
</li>
</ul>
</nav>
<section>
<h1 class="title">{{ $t("Instances") }}</h1>
<div class="tabs is-boxed">
@ -35,6 +54,7 @@
</div>
<router-view></router-view>
</section>
</div>
</template>
<script lang="ts">

View file

@ -1,4 +1,15 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{ $t("Moderation") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.PROFILES }">{{ $t("Profiles") }}</router-link>
</li>
</ul>
</nav>
<div v-if="persons">
<b-switch v-model="local">{{ $t("Local") }}</b-switch>
<b-switch v-model="suspended">{{ $t("Suspended") }}</b-switch>
@ -65,6 +76,7 @@
</template>
</b-table>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";

View file

@ -1,4 +1,17 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{ $t("Admin") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.ADMIN_SETTINGS }">{{
$t("Instance settings")
}}</router-link>
</li>
</ul>
</nav>
<section v-if="adminSettings">
<form @submit.prevent="updateSettings">
<b-field :label="$t('Instance Name')">
@ -44,7 +57,9 @@
<div class="field">
<label class="label has-help">{{ $t("Instance Rules") }}</label>
<small>
{{ $t("A place for your code of conduct, rules or guidelines. You can use HTML tags.") }}
{{
$t("A place for your code of conduct, rules or guidelines. You can use HTML tags.")
}}
</small>
<b-input type="textarea" v-model="adminSettings.instanceRules" />
</div>
@ -196,7 +211,9 @@
v-if="adminSettings.instancePrivacyPolicyType === InstancePrivacyType.URL"
>
<b>{{ $t("URL") }}</b>
<p class="content">{{ $t("Set an URL to a page with your own privacy policy.") }}</p>
<p class="content">
{{ $t("Set an URL to a page with your own privacy policy.") }}
</p>
</div>
<div
class="notification"
@ -236,6 +253,7 @@
<b-button native-type="submit" type="is-primary">{{ $t("Save") }}</b-button>
</form>
</section>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

View file

@ -1,4 +1,15 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{ $t("Moderation") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.USERS }">{{ $t("Users") }}</router-link>
</li>
</ul>
</nav>
<div v-if="users">
<b-table
:data="users.elements"
@ -73,6 +84,7 @@
</template>
</b-table>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

View file

@ -756,9 +756,9 @@ export default class Event extends EventMixin {
});
});
this.$on('eventDeleted', () => {
this.$on("eventDeleted", () => {
return this.$router.push({ name: RouteName.HOME });
})
});
}
/**

View file

@ -1,4 +1,20 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.GROUP }">{{ group.name }}</router-link>
</li>
<li>
<router-link :to="{ name: RouteName.GROUP_SETTINGS }">{{ $t("Settings") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.GROUP_MEMBERS_SETTINGS }">{{
$t("Members")
}}</router-link>
</li>
</ul>
</nav>
<section class="container section" v-if="group">
<form @submit.prevent="inviteMember">
<b-field :label="$t('Invite a new member')" custom-class="add-relay" horizontal>
@ -15,6 +31,7 @@
<h1>{{ $t("Group Members") }} ({{ group.members.total }})</h1>
<pre>{{ group.members }}</pre>
</section>
</div>
</template>
<script lang="ts">

View file

@ -2,19 +2,21 @@
<aside class="section container">
<h1 class="title">{{ $t("Settings") }}</h1>
<div class="columns">
<SettingsMenu class="column is-one-quarter-desktop" :menu="menu" />
<div class="column">
<nav class="breadcrumb" aria-label="breadcrumbs">
<aside class="column is-one-quarter-desktop">
<ul>
<li
v-for="route in routes.get($route.name)"
:class="{ 'is-active': route.to.name === $route.name }"
:key="route.title"
>
<router-link :to="{ name: route.to.name }">{{ route.title }}</router-link>
</li>
<SettingMenuSection :title="$t('Settings')" :to="{ name: RouteName.GROUP_SETTINGS }">
<SettingMenuItem
:title="this.$t('Public')"
:to="{ name: RouteName.GROUP_PUBLIC_SETTINGS }"
/>
<SettingMenuItem
:title="this.$t('Members')"
:to="{ name: RouteName.GROUP_MEMBERS_SETTINGS }"
/>
</SettingMenuSection>
</ul>
</nav>
</aside>
<div class="column">
<router-view />
</div>
</div>
@ -22,70 +24,20 @@
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import SettingsMenu from "@/components/Settings/SettingsMenu.vue";
import { ISettingMenuSection } from "@/types/setting-menu.model";
import { Route } from "vue-router";
import { IGroup, IPerson } from "@/types/actor";
import { FETCH_GROUP } from "@/graphql/actor";
import RouteName from "../../router/name";
import SettingMenuSection from "../../components/Settings/SettingMenuSection.vue";
import SettingMenuItem from "../../components/Settings/SettingMenuItem.vue";
@Component({
components: { SettingsMenu },
apollo: {
group: {
query: FETCH_GROUP,
},
},
components: { SettingMenuSection, SettingMenuItem },
})
export default class Settings extends Vue {
RouteName = RouteName;
menu: ISettingMenuSection[] = [];
group!: IGroup[];
mounted() {
this.menu = [
{
title: this.$t("Settings") as string,
to: { name: RouteName.GROUP_SETTINGS } as Route,
items: [
{
title: this.$t("Public") as string,
to: { name: RouteName.GROUP_PUBLIC_SETTINGS } as Route,
},
{
title: this.$t("Members") as string,
to: { name: RouteName.GROUP_MEMBERS_SETTINGS } as Route,
},
],
},
];
}
get routes(): Map<string, Route[]> {
return this.getPath(this.menu);
}
getPath(object: ISettingMenuSection[]) {
function iter(menu: ISettingMenuSection[] | ISettingMenuSection, acc: ISettingMenuSection[]) {
if (Array.isArray(menu)) {
return menu.forEach((item: ISettingMenuSection) => {
iter(item, acc.concat(item));
});
}
if (menu.items && menu.items.length > 0) {
return menu.items.forEach((item: ISettingMenuSection) => {
iter(item, acc.concat(item));
});
}
result.set(menu.to.name, acc);
}
const result = new Map();
iter(object, []);
return result;
}
}
</script>

View file

@ -1,4 +1,17 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{ $t("Moderation") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.REPORT_LOGS }">{{
$t("Moderation log")
}}</router-link>
</li>
</ul>
</nav>
<section>
<ul v-if="actionLogs.length > 0">
<li v-for="log in actionLogs" :key="log.id">
@ -141,6 +154,7 @@
<b-message type="is-info">{{ $t("No moderation logs yet") }}</b-message>
</div>
</section>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

View file

@ -1,4 +1,20 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs" v-if="report">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{ $t("Moderation") }}</router-link>
</li>
<li>
<router-link :to="{ name: RouteName.REPORTS }">{{ $t("Reports") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.REPORT, params: { id: report.id } }">{{
$t("Report #{reportNumber}", { reportNumber: report.id })
}}</router-link>
</li>
</ul>
</nav>
<section>
<b-message title="Error" type="is-danger" v-for="error in errors" :key="error">
{{ error }}
@ -197,6 +213,7 @@
</form>
</div>
</section>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";

View file

@ -1,4 +1,15 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{ $t("Moderation") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.REPORTS }">{{ $t("Reports") }}</router-link>
</li>
</ul>
</nav>
<section>
<b-field>
<b-radio-button v-model="filterReports" :native-value="ReportStatusEnum.OPEN">{{
@ -30,6 +41,7 @@
</b-message>
</div>
</section>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";

View file

@ -2,19 +2,8 @@
<div class="section container">
<h1 class="title">{{ $t("Settings") }}</h1>
<div class="columns">
<SettingsMenu class="column is-one-quarter-desktop" :menu="menu" />
<SettingsMenu class="column is-one-quarter-desktop" />
<div class="column">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li
v-for="route in routes.get($route.name)"
:class="{ 'is-active': route.to.name === $route.name }"
:key="route.to.name"
>
<router-link :to="{ name: route.to.name }">{{ route.title }}</router-link>
</li>
</ul>
</nav>
<router-view />
</div>
</div>
@ -25,7 +14,6 @@ import { Component, Vue, Watch } from "vue-property-decorator";
import { Route } from "vue-router";
import SettingsMenu from "../components/Settings/SettingsMenu.vue";
import RouteName from "../router/name";
import { ISettingMenuSection } from "../types/setting-menu.model";
import { IPerson, Person } from "../types/actor";
import { IDENTITIES } from "../graphql/actor";
import { CURRENT_USER_CLIENT } from "../graphql/user";
@ -44,148 +32,9 @@ import { ICurrentUser, ICurrentUserRole } from "../types/current-user.model";
export default class Settings extends Vue {
RouteName = RouteName;
menu: ISettingMenuSection[] = [];
identities!: IPerson[];
newIdentity!: ISettingMenuSection;
currentUser!: ICurrentUser;
mounted() {
this.newIdentity = {
title: this.$t("New profile") as string,
to: { name: RouteName.CREATE_IDENTITY } as Route,
};
this.menu = [
{
title: this.$t("Account") as string,
to: { name: RouteName.ACCOUNT_SETTINGS } as Route,
items: [
{
title: this.$t("General") as string,
to: { name: RouteName.ACCOUNT_SETTINGS_GENERAL } as Route,
},
{
title: this.$t("Preferences") as string,
to: { name: RouteName.PREFERENCES } as Route,
},
{
title: this.$t("Email notifications") as string,
to: { name: RouteName.NOTIFICATIONS } as Route,
},
],
},
{
title: this.$t("Profiles") as string,
to: { name: RouteName.IDENTITIES } as Route,
items: [this.newIdentity],
},
];
if (
[ICurrentUserRole.MODERATOR, ICurrentUserRole.ADMINISTRATOR].includes(this.currentUser.role)
) {
this.menu.push({
title: this.$t("Moderation") as string,
to: { name: RouteName.MODERATION } as Route,
items: [
{
title: this.$t("Reports") as string,
to: { name: RouteName.REPORTS } as Route,
items: [
{
title: this.$t("Report") as string,
to: { name: RouteName.REPORT } as Route,
},
],
},
{
title: this.$t("Moderation log") as string,
to: { name: RouteName.REPORT_LOGS } as Route,
},
{
title: this.$t("Users") as string,
to: { name: RouteName.USERS } as Route,
},
{
title: this.$t("Profiles") as string,
to: { name: RouteName.PROFILES } as Route,
},
],
});
}
if (this.currentUser.role === ICurrentUserRole.ADMINISTRATOR) {
this.menu.push({
title: this.$t("Admin") as string,
to: { name: RouteName.ADMIN } as Route,
items: [
{
title: this.$t("Dashboard") as string,
to: { name: RouteName.ADMIN_DASHBOARD } as Route,
},
{
title: this.$t("Instance settings") as string,
to: { name: RouteName.ADMIN_SETTINGS } as Route,
},
{
title: this.$t("Federation") as string,
to: { name: RouteName.RELAYS } as Route,
items: [
{
title: this.$t("Followings") as string,
to: { name: RouteName.RELAY_FOLLOWINGS } as Route,
},
{
title: this.$t("Followers") as string,
to: { name: RouteName.RELAY_FOLLOWERS } as Route,
},
],
},
],
});
}
}
@Watch("identities")
updateIdentities(identities: IPerson[]) {
if (!identities) return;
if (!this.menu[1].items) return;
this.menu[1].items = [];
this.menu[1].items.push(
...identities.map((identity: IPerson) => ({
to: ({
name: RouteName.UPDATE_IDENTITY,
params: { identityName: identity.preferredUsername },
} as unknown) as Route,
title: `@${identity.preferredUsername}`,
}))
);
this.menu[1].items.push(this.newIdentity);
}
get routes(): Map<string, Route[]> {
return this.getPath(this.menu);
}
getPath(object: ISettingMenuSection[]) {
function iter(menu: ISettingMenuSection[] | ISettingMenuSection, acc: ISettingMenuSection[]) {
if (Array.isArray(menu)) {
return menu.forEach((item: ISettingMenuSection) => {
iter(item, acc.concat(item));
});
}
if (menu.items && menu.items.length > 0) {
return menu.items.forEach((item: ISettingMenuSection) => {
iter(item, acc.concat(item));
});
}
result.set(menu.to.name, acc);
}
const result = new Map();
iter(object, []);
return result;
}
}
</script>

View file

@ -1,4 +1,17 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ACCOUNT_SETTINGS }">{{ $t("Account") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.ACCOUNT_SETTINGS_GENERAL }">{{
$t("General")
}}</router-link>
</li>
</ul>
</nav>
<section>
<div class="setting-title">
<h2>{{ $t("Email") }}</h2>
@ -140,6 +153,7 @@
</section>
</b-modal>
</section>
</div>
</template>
<script lang="ts">

View file

@ -1,5 +1,17 @@
<template>
<div v-if="loggedUser">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ACCOUNT_SETTINGS }">{{ $t("Account") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.NOTIFICATIONS }">{{
$t("Email notifications")
}}</router-link>
</li>
</ul>
</nav>
<section>
<div class="setting-title">
<h2>{{ $t("Participation notifications") }}</h2>

View file

@ -1,4 +1,15 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ACCOUNT_SETTINGS }">{{ $t("Account") }}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.PREFERENCES }">{{ $t("Preferences") }}</router-link>
</li>
</ul>
</nav>
<div>
<b-field :label="$t('Language')">
<b-select
@ -34,6 +45,7 @@
})
}}</em>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
@ -42,6 +54,7 @@ import { USER_SETTINGS, SET_USER_SETTINGS, UPDATE_USER_LOCALE } from "../../grap
import { IConfig } from "../../types/config.model";
import { ICurrentUser } from "../../types/current-user.model";
import langs from "../../i18n/langs.json";
import RouteName from "../../router/name";
@Component({
apollo: {
@ -58,6 +71,8 @@ export default class Preferences extends Vue {
locale: string | null = null;
RouteName = RouteName;
@Watch("loggedUser")
setSavedTimezone(loggedUser: ICurrentUser) {
if (loggedUser && loggedUser.settings.timezone) {

View file

@ -1144,9 +1144,9 @@
"@types/geojson" "*"
"@types/lodash@^4.14.141":
version "4.14.156"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.156.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1"
integrity sha512-l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8lQ==
version "4.14.157"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.157.tgz#fdac1c52448861dfde1a2e1515dbc46e54926dc8"
integrity sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ==
"@types/minimatch@*":
version "3.0.3"
@ -1164,9 +1164,9 @@
integrity sha512-6nlq2eEh75JegDGUXis9wGTYIJpUvbori4qx++PRKQsV3YRkaqUNPNykzphniqPSZADXCouBuAnyptjUkMkhvw==
"@types/node@*", "@types/node@>=6":
version "14.0.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9"
integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==
version "14.0.14"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.14.tgz#24a0b5959f16ac141aeb0c5b3cd7a15b7c64cbce"
integrity sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@ -1629,14 +1629,14 @@
prettier "^1.18.2"
"@vue/eslint-config-airbnb@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@vue/eslint-config-airbnb/-/eslint-config-airbnb-5.0.2.tgz#4e3ba49e8d7a7c0bf6b244b4d7a2fe488bfb9371"
integrity sha512-9wD5OfdkQ0TDYLRynP46AxOHck866zkvZoT8MgjyJNBPegTtrsIQ3cu10ZF4Nl/aU5qKeSOaY58D4YXPqF0NZg==
version "5.1.0"
resolved "https://registry.yarnpkg.com/@vue/eslint-config-airbnb/-/eslint-config-airbnb-5.1.0.tgz#6a72e166af18ac821120ff36aae8b76b940f28aa"
integrity sha512-kme7oQRb3AY8UWd3X7d/uTkmrsbkhwcxhS7rvbxdvfJykLDy4GtO4MdQhmKWa7b8R/gjIMfBXaCN6XUZU9PC6Q==
dependencies:
eslint-config-airbnb-base "^14.0.0"
eslint-import-resolver-node "^0.3.3"
eslint-import-resolver-webpack "^0.11.1"
eslint-plugin-import "^2.18.2"
eslint-import-resolver-node "^0.3.4"
eslint-import-resolver-webpack "^0.12.2"
eslint-plugin-import "^2.21.2"
"@vue/eslint-config-prettier@^6.0.0":
version "6.0.0"
@ -2523,13 +2523,13 @@ atob@^2.1.2:
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
autoprefixer@^9.8.0:
version "9.8.2"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.2.tgz#7347396ee576b18687041bfbacd76d78e27baa56"
integrity sha512-9UwMMU8Rg7Fj0c55mbOpXrr/2WrRqoOwOlLNTyyYt+nhiyQdIBWipp5XWzt+Lge8r3DK5y+EHMc1OBf8VpZA6Q==
version "9.8.4"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.4.tgz#736f1012673a70fa3464671d78d41abd54512863"
integrity sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A==
dependencies:
browserslist "^4.12.0"
caniuse-lite "^1.0.30001084"
kleur "^4.0.1"
caniuse-lite "^1.0.30001087"
colorette "^1.2.0"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
postcss "^7.0.32"
@ -2919,14 +2919,14 @@ browserslist@4.7.0:
node-releases "^1.1.29"
browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5:
version "4.12.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d"
integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==
version "4.12.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.1.tgz#6d08bef149b70d153930780ba762644e0f329122"
integrity sha512-WMjXwFtPskSW1pQUDJRxvRKRkeCr7usN0O/Za76N+F4oadaTdQHotSGcX9jT/Hs7mSKPkyMFNvqawB/1HzYDKQ==
dependencies:
caniuse-lite "^1.0.30001043"
electron-to-chromium "^1.3.413"
node-releases "^1.1.53"
pkg-up "^2.0.0"
caniuse-lite "^1.0.30001088"
electron-to-chromium "^1.3.481"
escalade "^3.0.1"
node-releases "^1.1.58"
buble@0.19.8, buble@^0.19.7:
version "0.19.8"
@ -3185,10 +3185,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000929, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001084:
version "1.0.30001087"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001087.tgz#4a0bdc5998a114fcf8b7954e7ba6c2c29831c54a"
integrity sha512-KAQRGtt+eGCQBSp2iZTQibdCf9oe6cNTi5lmpsW38NnxP4WMYzfU6HCRmh4kJyh6LrTM9/uyElK4xcO93kafpg==
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000929, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001087, caniuse-lite@^1.0.30001088:
version "1.0.30001088"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001088.tgz#23a6b9e192106107458528858f2c0e0dba0d9073"
integrity sha512-6eYUrlShRYveyqKG58HcyOfPgh3zb2xqs7NvT2VVtP3hEUeeWvc3lqhpeMTxYWBBeeaT9A4bKsrtjATm66BTHg==
capture-stack-trace@^1.0.0:
version "1.0.1"
@ -3692,6 +3692,11 @@ color@^3.0.0:
color-convert "^1.9.1"
color-string "^1.5.2"
colorette@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.0.tgz#45306add826d196e8c87236ac05d797f25982e63"
integrity sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw==
colors@^1.1.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
@ -4445,7 +4450,7 @@ de-indent@^1.0.2:
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9:
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@ -4932,10 +4937,10 @@ ejs@^2.6.1:
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba"
integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==
electron-to-chromium@^1.3.103, electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.413:
version "1.3.481"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.481.tgz#0d59e72a0aaeb876b43fb1d6e84bf0dfc99617e8"
integrity sha512-q2PeCP2PQXSYadDo9uNY+uHXjdB9PcsUpCVoGlY8TZOPHGlXdevlqW9PkKeqCxn2QBkGB8b6AcMO++gh8X82bA==
electron-to-chromium@^1.3.103, electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.481:
version "1.3.483"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.483.tgz#9269e7cfc1c8e72709824da171cbe47ca5e3ca9e"
integrity sha512-+05RF8S9rk8S0G8eBCqBRBaRq7+UN3lDs2DAvnG8SBSgQO3hjy0+qt4CmRk5eiuGbTcaicgXfPmBi31a+BD3lg==
elegant-spinner@^1.0.1:
version "1.0.1"
@ -4999,6 +5004,15 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
enhanced-resolve@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e"
integrity sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=
dependencies:
graceful-fs "^4.1.2"
memory-fs "^0.2.0"
tapable "^0.1.8"
enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d"
@ -5008,15 +5022,6 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1:
memory-fs "^0.5.0"
tapable "^1.0.0"
enhanced-resolve@~0.9.0:
version "0.9.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e"
integrity sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=
dependencies:
graceful-fs "^4.1.2"
memory-fs "^0.2.0"
tapable "^0.1.8"
entities@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
@ -5091,6 +5096,11 @@ es6-promisify@^5.0.0:
dependencies:
es6-promise "^4.0.3"
escalade@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.1.tgz#52568a77443f6927cd0ab9c73129137533c965ed"
integrity sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA==
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@ -5129,7 +5139,7 @@ eslint-config-prettier@^6.0.0, eslint-config-prettier@^6.11.0:
dependencies:
get-stdin "^6.0.0"
eslint-import-resolver-node@^0.3.3:
eslint-import-resolver-node@^0.3.3, eslint-import-resolver-node@^0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717"
integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==
@ -5137,21 +5147,21 @@ eslint-import-resolver-node@^0.3.3:
debug "^2.6.9"
resolve "^1.13.1"
eslint-import-resolver-webpack@^0.11.1:
version "0.11.1"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.11.1.tgz#fcf1fd57a775f51e18f442915f85dd6ba45d2f26"
integrity sha512-eK3zR7xVQR/MaoBWwGuD+CULYVuqe5QFlDukman71aI6IboCGzggDUohHNfu1ZeBnbHcUHJc0ywWoXUBNB6qdg==
eslint-import-resolver-webpack@^0.12.2:
version "0.12.2"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.2.tgz#769e86cd0c752a1536c19855ebd90aa14ce384ee"
integrity sha512-7Jnm4YAoNNkvqPaZkKdIHsKGmv8/uNnYC5QsXkiSodvX4XEEfH2AKOna98FK52fCDXm3q4HzuX+7pRMKkJ64EQ==
dependencies:
array-find "^1.0.0"
debug "^2.6.8"
enhanced-resolve "~0.9.0"
debug "^2.6.9"
enhanced-resolve "^0.9.1"
find-root "^1.1.0"
has "^1.0.1"
interpret "^1.0.0"
lodash "^4.17.4"
has "^1.0.3"
interpret "^1.2.0"
lodash "^4.17.15"
node-libs-browser "^1.0.0 || ^2.0.0"
resolve "^1.10.0"
semver "^5.3.0"
resolve "^1.13.1"
semver "^5.7.1"
eslint-loader@^2.2.1:
version "2.2.1"
@ -5179,7 +5189,7 @@ eslint-plugin-cypress@^2.10.3:
dependencies:
globals "^11.12.0"
eslint-plugin-import@^2.18.2, eslint-plugin-import@^2.20.2:
eslint-plugin-import@^2.20.2, eslint-plugin-import@^2.21.2:
version "2.21.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c"
integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==
@ -6736,7 +6746,7 @@ has-yarn@^2.1.0:
resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
has@^1.0.0, has@^1.0.1, has@^1.0.3:
has@^1.0.0, has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
@ -7261,7 +7271,7 @@ internal-ip@^4.3.0:
default-gateway "^4.2.0"
ipaddr.js "^1.9.0"
interpret@^1.0.0, interpret@^1.2.0, interpret@^1.4.0:
interpret@^1.2.0, interpret@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
@ -7846,9 +7856,9 @@ jest-worker@^25.4.0:
supports-color "^7.0.0"
js-base64@^2.1.8, js-base64@^2.1.9, js-base64@^2.3.2:
version "2.6.1"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.1.tgz#c328374225d2e65569791ded73c258e2c59334c7"
integrity sha512-G5x2saUTupU9D/xBY9snJs3TxvwX8EkpLFiYlPpDt/VmMHOXprnSU1nxiTmFbijCX4BLF/cMRIfAcC5BiMYgFQ==
version "2.6.2"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.2.tgz#cf9301bc5cc756892a9a6c8d7138322e5944fb0d"
integrity sha512-1hgLrLIrmCgZG+ID3VoLNLOSwjGnoZa8tyrUdEteMeIzsT6PH7PMLyUvbDwzNE56P3PNxyvuIOx4Uh2E5rzQIw==
js-beautify@^1.6.12:
version "1.11.0"
@ -8212,11 +8222,6 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
kleur@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.0.1.tgz#3d4948534b666e2578f93b6fafb62108e64f05ef"
integrity sha512-Qs6SqCLm63rd0kNVh+wO4XsWLU6kgfwwaPYsLiClWf0Tewkzsa6MvB21bespb8cz+ANS+2t3So1ge3gintzhlw==
latest-version@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
@ -9386,7 +9391,7 @@ node-ipc@^9.1.1:
util "^0.11.0"
vm-browserify "^1.0.1"
node-releases@^1.1.29, node-releases@^1.1.3, node-releases@^1.1.53:
node-releases@^1.1.29, node-releases@^1.1.3, node-releases@^1.1.58:
version "1.1.58"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.58.tgz#8ee20eef30fa60e52755fcc0942def5a734fe935"
integrity sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==
@ -10286,7 +10291,7 @@ pkg-dir@^4.1.0:
dependencies:
find-up "^4.0.0"
pkg-up@2.0.0, pkg-up@^2.0.0:
pkg-up@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
integrity sha1-yBmscoBZpGHKscOImivjxJoATX8=
@ -11019,9 +11024,9 @@ prosemirror-view@1.14.7:
prosemirror-transform "^1.1.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3:
version "1.14.13"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.14.13.tgz#c86967b2679652ae21f610620f5089ba654cb413"
integrity sha512-UmAAi72eHApZ6KMklUTORc9FkmGXyeI+rWtqxqZ+6V4vs6K6spbOVozQChKmtVL2EjQlOILvJIJdWKWu0Hkvpw==
version "1.15.0"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.15.0.tgz#372102c91d05b3b0f371b3eb59aeacedb5011bba"
integrity sha512-a7Q76sO/DCZr2UX2Rv1Rbw52cr9kVIz8iJOf/rq4mPN1NA3lugq2BKJgUMwlB3U4utyw3olLigqouRHM48NJyg==
dependencies:
prosemirror-model "^1.1.0"
prosemirror-state "^1.0.0"
@ -12292,7 +12297,7 @@ semver-diff@^2.0.0:
dependencies:
semver "^5.0.3"
"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0:
"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@ -14314,9 +14319,9 @@ vue-inbrowser-compiler@^4.23.3:
walkes "^0.2.1"
vue-loader@^15.9.2:
version "15.9.2"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.2.tgz#ae01f5f4c9c6a04bff4483912e72ef91a402c1ae"
integrity sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA==
version "15.9.3"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.3.tgz#0de35d9e555d3ed53969516cac5ce25531299dda"
integrity sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==
dependencies:
"@vue/component-compiler-utils" "^3.1.0"
hash-sum "^1.0.2"