refactor(ui): teams
This commit is contained in:
@@ -118,7 +118,7 @@ a {
|
||||
}
|
||||
|
||||
.popover-theme {
|
||||
@apply bg-primary;
|
||||
@apply bg-popover;
|
||||
@apply text-secondary;
|
||||
@apply p-2;
|
||||
@apply shadow-lg;
|
||||
@@ -126,19 +126,19 @@ a {
|
||||
}
|
||||
|
||||
&[x-placement^="top"] .tippy-tooltip .tippy-arrow {
|
||||
@apply border-t-primary;
|
||||
@apply border-t-popover;
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] .tippy-tooltip .tippy-arrow {
|
||||
@apply border-b-primary;
|
||||
@apply border-b-popover;
|
||||
}
|
||||
|
||||
&[x-placement^="left"] .tippy-tooltip .tippy-arrow {
|
||||
@apply border-l-primary;
|
||||
@apply border-l-popover;
|
||||
}
|
||||
|
||||
&[x-placement^="right"] .tippy-tooltip .tippy-arrow {
|
||||
@apply border-r-primary;
|
||||
@apply border-r-popover;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
--error-color: theme("colors.dark.800");
|
||||
// Tooltip color
|
||||
--tooltip-color: theme("colors.true-gray.100");
|
||||
// Popover color
|
||||
--popover-color: theme("colors.true-gray.800");
|
||||
// Editor theme
|
||||
--editor-theme: "merbivore_soft";
|
||||
}
|
||||
@@ -54,6 +56,8 @@
|
||||
--error-color: theme("colors.blue-gray.700");
|
||||
// Tooltip color
|
||||
--tooltip-color: theme("colors.blue-gray.800");
|
||||
// Popover color
|
||||
--popover-color: theme("colors.white");
|
||||
// Editor theme
|
||||
--editor-theme: "textmate";
|
||||
}
|
||||
@@ -81,6 +85,8 @@
|
||||
--error-color: theme("colors.dark.800");
|
||||
// Tooltip color
|
||||
--tooltip-color: theme("colors.true-gray.100");
|
||||
// Popover color
|
||||
--popover-color: theme("colors.dark.700");
|
||||
// Editor theme
|
||||
--editor-theme: "twilight";
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
'<br>' +
|
||||
`<sub>${currentUser.email || 'Email not found'}</sub>`
|
||||
"
|
||||
:indicator="isOnLine ? 'bg-green-500' : 'bg-red-500'"
|
||||
indicator
|
||||
:indicator-styles="isOnLine ? 'bg-green-500' : 'bg-red-500'"
|
||||
/>
|
||||
<TabPrimary
|
||||
v-else
|
||||
|
||||
@@ -27,10 +27,11 @@
|
||||
transition
|
||||
w-28
|
||||
truncate
|
||||
focus:outline-none focus:border-accent
|
||||
focus:border-accent focus:outline-none
|
||||
"
|
||||
:value="newMethod"
|
||||
readonly
|
||||
:readonly="isCustomMethod()"
|
||||
@input="onSelectMethod($event.target.value)"
|
||||
/>
|
||||
</template>
|
||||
<SmartItem
|
||||
@@ -78,7 +79,7 @@
|
||||
px-4
|
||||
transition
|
||||
truncate
|
||||
focus:outline-none focus:border-accent
|
||||
focus:border-accent focus:outline-none
|
||||
"
|
||||
name="url"
|
||||
type="text"
|
||||
@@ -332,6 +333,7 @@ export default defineComponent({
|
||||
updateMethod(methods[currentIndex - 1])
|
||||
}
|
||||
}
|
||||
|
||||
const cycleDownMethod = () => {
|
||||
const currentIndex = methods.indexOf(newMethod.value)
|
||||
if (currentIndex === -1) {
|
||||
@@ -363,6 +365,12 @@ export default defineComponent({
|
||||
defineActionHandler("request.method.delete", () => updateMethod("DELETE"))
|
||||
defineActionHandler("request.method.head", () => updateMethod("HEAD"))
|
||||
|
||||
const isCustomMethod = () => {
|
||||
if (newMethod.value === "CUSTOM" || !methods.includes(newMethod.value))
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
return {
|
||||
newEndpoint,
|
||||
newMethod,
|
||||
@@ -386,6 +394,8 @@ export default defineComponent({
|
||||
methodOptions,
|
||||
sendOptions,
|
||||
saveOptions,
|
||||
|
||||
isCustomMethod,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
/>
|
||||
<div class="rounded-full shadow-inner inset-0 absolute"></div>
|
||||
<span
|
||||
v-if="indicator"
|
||||
:class="[
|
||||
'border-primary rounded-full border-2 h-3 -top-1 -right-1 w-3 absolute',
|
||||
indicator,
|
||||
indicatorStyles,
|
||||
]"
|
||||
></span>
|
||||
</div>
|
||||
@@ -38,6 +39,10 @@ export default {
|
||||
default: "Profile picture",
|
||||
},
|
||||
indicator: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
indicatorStyles: {
|
||||
type: String,
|
||||
default: "bg-green-500",
|
||||
},
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
<SmartModal v-if="show" @close="hideModal">
|
||||
<template #header>
|
||||
<h3 class="heading">{{ $t("team.edit") }}</h3>
|
||||
<div>
|
||||
<ButtonSecondary icon="close" @click.native="hideModal" />
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
@@ -58,7 +56,7 @@
|
||||
/>
|
||||
<span class="select-wrapper">
|
||||
<tippy
|
||||
ref="options"
|
||||
ref="memberOptions"
|
||||
interactive
|
||||
tabindex="-1"
|
||||
trigger="click"
|
||||
@@ -89,22 +87,22 @@
|
||||
<SmartItem
|
||||
label="OWNER"
|
||||
@click.native="
|
||||
updateRole(index, 'OWNER')
|
||||
$refs.options.tippy().hide()
|
||||
$refs.memberOptions.tippy().hide()
|
||||
updateMemberRole(index, 'OWNER')
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
label="EDITOR"
|
||||
@click.native="
|
||||
updateRole(index, 'EDITOR')
|
||||
$refs.options.tippy().hide()
|
||||
$refs.memberOptions.tippy().hide()
|
||||
updateMemberRole(index, 'EDITOR')
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
label="VIEWER"
|
||||
@click.native="
|
||||
updateRole(index, 'VIEWER')
|
||||
$refs.options.tippy().hide()
|
||||
$refs.memberOptions.tippy().hide()
|
||||
updateMemberRole(index, 'VIEWER')
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
@@ -122,7 +120,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-for="(member, index) in newMembers"
|
||||
:key="`member-${index}`"
|
||||
:key="`new-member-${index}`"
|
||||
class="
|
||||
divide-x divide-dividerLight
|
||||
border-b border-dividerLight
|
||||
@@ -146,7 +144,7 @@
|
||||
/>
|
||||
<span class="select-wrapper">
|
||||
<tippy
|
||||
ref="memberOptions"
|
||||
ref="newMemberOptions"
|
||||
interactive
|
||||
tabindex="-1"
|
||||
trigger="click"
|
||||
@@ -177,22 +175,22 @@
|
||||
<SmartItem
|
||||
label="OWNER"
|
||||
@click.native="
|
||||
member.value = 'OWNER'
|
||||
$refs.memberOptions.tippy().hide()
|
||||
$refs.newMemberOptions.tippy().hide()
|
||||
updateNewMemberRole(index, 'OWNER')
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
label="EDITOR"
|
||||
@click.native="
|
||||
member.value = 'EDITOR'
|
||||
$refs.memberOptions.tippy().hide()
|
||||
$refs.newMemberOptions.tippy().hide()
|
||||
updateNewMemberRole(index, 'EDITOR')
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
label="VIEWER"
|
||||
@click.native="
|
||||
member.value = 'VIEWER'
|
||||
$refs.memberOptions.tippy().hide()
|
||||
$refs.newMemberOptions.tippy().hide()
|
||||
updateNewMemberRole(index, 'VIEWER')
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
@@ -222,10 +220,11 @@
|
||||
|
||||
<script>
|
||||
import cloneDeep from "lodash/cloneDeep"
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import * as teamUtils from "~/helpers/teams/utils"
|
||||
import TeamMemberAdapter from "~/helpers/teams/TeamMemberAdapter"
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
editingTeam: { type: Object, default: () => {} },
|
||||
@@ -263,12 +262,15 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
updateRole(id, role) {
|
||||
updateMemberRole(id, role) {
|
||||
this.members[id].role = role
|
||||
},
|
||||
updateNewMemberRole(id, role) {
|
||||
this.newMembers[id].value = role
|
||||
},
|
||||
addTeamMember() {
|
||||
const value = { key: "", value: "" }
|
||||
this.newMembers.push(value)
|
||||
const member = { key: "", value: "" }
|
||||
this.newMembers.push(member)
|
||||
},
|
||||
removeExistingTeamMember(userID) {
|
||||
teamUtils
|
||||
@@ -409,5 +411,5 @@ export default {
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
<template>
|
||||
<div class="flex flex-1">
|
||||
<div>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="team.myRole === 'OWNER' ? $t('edit') : ''"
|
||||
icon="group"
|
||||
:label="team.name"
|
||||
@click.native="team.myRole === 'OWNER' ? $emit('edit-team') : ''"
|
||||
<div class="flex flex-1 items-end">
|
||||
<div class="flex flex-1 items-start">
|
||||
<div class="p-4">
|
||||
<label
|
||||
class="
|
||||
cursor-pointer
|
||||
font-semibold
|
||||
transition
|
||||
hover:text-secondaryDark
|
||||
"
|
||||
@click="team.myRole === 'OWNER' ? $emit('edit-team') : ''"
|
||||
>
|
||||
{{ team.name || $t("nothing_found") }}
|
||||
</label>
|
||||
<div class="flex -space-x-1 mt-2 overflow-hidden">
|
||||
<img
|
||||
v-for="(member, index) in team.members"
|
||||
:key="`member-${index}`"
|
||||
:src="member.user.photoURL"
|
||||
:alt="member.user.displayName"
|
||||
class="rounded-full h-4 ring-primary ring-2 w-4 inline-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span>
|
||||
<tippy
|
||||
ref="options"
|
||||
interactive
|
||||
@@ -18,7 +34,7 @@
|
||||
arrow
|
||||
>
|
||||
<template #trigger>
|
||||
<TabPrimary
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('more')"
|
||||
icon="more_vert"
|
||||
@@ -59,6 +75,7 @@
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,22 +1,44 @@
|
||||
<template>
|
||||
<AppSection label="teams">
|
||||
<div class="flex flex-col">
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("team.title") }}
|
||||
</legend>
|
||||
<div v-if="currentUser"></div>
|
||||
<div v-else>
|
||||
<label>{{ $t("login_with") }}</label>
|
||||
<p>
|
||||
<ButtonPrimary
|
||||
v-if="currentUser"
|
||||
label="Get Started"
|
||||
@click.native="showLogin = true"
|
||||
</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
Join
|
||||
<SmartAnchor label="beta" to="https://hoppscotch.io/beta" blank />
|
||||
to access teams.
|
||||
</div>
|
||||
<div class="space-y-4 mt-4">
|
||||
<ButtonSecondary
|
||||
:label="$t('team.create_new')"
|
||||
outline
|
||||
@click.native="displayModalAdd(true)"
|
||||
/>
|
||||
<p v-if="$apollo.queries.myTeams.loading">
|
||||
{{ $t("loading") }}
|
||||
</p>
|
||||
<p v-if="myTeams.length === 0">
|
||||
<i class="material-icons">help_outline</i> {{ $t("team.create_new") }}
|
||||
</p>
|
||||
<div
|
||||
v-else
|
||||
class="
|
||||
divide-y divide-dividerLight
|
||||
border border-divider
|
||||
rounded
|
||||
flex flex-col flex-1
|
||||
md:w-64
|
||||
"
|
||||
>
|
||||
<TeamsTeam
|
||||
v-for="(team, index) in myTeams"
|
||||
:key="`team-${index}`"
|
||||
:team-i-d="team.id"
|
||||
:team="team"
|
||||
@edit-team="editTeam(team, team.id)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TeamsAdd :show="showModalAdd" @hide-modal="displayModalAdd(false)" />
|
||||
<TeamsEdit
|
||||
:team="myTeams[0]"
|
||||
@@ -25,33 +47,6 @@
|
||||
:editingteam-i-d="editingteamID"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
/>
|
||||
<div class="flex flex-1">
|
||||
<div>
|
||||
<ButtonSecondary
|
||||
icon="add"
|
||||
:label="$t('new')"
|
||||
@click.native="displayModalAdd(true)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="$apollo.queries.myTeams.loading">
|
||||
{{ $t("loading") }}
|
||||
</p>
|
||||
<p v-if="myTeams.length === 0">
|
||||
<i class="material-icons">help_outline</i> {{ $t("team.create_new") }}
|
||||
</p>
|
||||
<div v-else class="hide-scrollbar !overflow-auto">
|
||||
<ul class="flex-col">
|
||||
<li v-for="(team, index) in myTeams" :key="`team-${index}`">
|
||||
<TeamsTeam
|
||||
:team-i-d="team.id"
|
||||
:team="team"
|
||||
@edit-team="editTeam(team, team.id)"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||
</AppSection>
|
||||
</template>
|
||||
|
||||
@@ -68,7 +63,6 @@ export default {
|
||||
editingteamID: "",
|
||||
me: {},
|
||||
myTeams: [],
|
||||
showLogin: false,
|
||||
}
|
||||
},
|
||||
subscriptions() {
|
||||
@@ -98,6 +92,7 @@ export default {
|
||||
ownersCount
|
||||
members {
|
||||
user {
|
||||
photoURL
|
||||
displayName
|
||||
email
|
||||
uid
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="divide-y divide-dividerLight space-y-8">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||
<div class="md:grid md:gap-4 md:grid-cols-3">
|
||||
<div class="p-8 md:col-span-1">
|
||||
<h3 class="heading">
|
||||
{{ $t("account") }}
|
||||
@@ -16,8 +16,8 @@
|
||||
<div class="mt-4 text-secondaryLight">Log in to access.</div>
|
||||
</div>
|
||||
<div v-else class="space-y-8">
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">User</legend>
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">User</h4>
|
||||
<div class="space-y-4 mt-4">
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center">
|
||||
@@ -29,7 +29,7 @@
|
||||
<i v-else class="material-icons">account_circle</i>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<label>
|
||||
<label class="font-semibold">
|
||||
{{ currentUser.displayName || $t("nothing_found") }}
|
||||
</label>
|
||||
<p class="mt-1 text-secondaryLight">
|
||||
@@ -42,7 +42,7 @@
|
||||
<i class="material-icons">email</i>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<label>
|
||||
<label class="font-semibold">
|
||||
{{ currentUser.email || $t("nothing_found") }}
|
||||
</label>
|
||||
<p class="mt-1 text-secondaryLight">
|
||||
@@ -51,9 +51,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">Sync</legend>
|
||||
</section>
|
||||
<Teams v-if="currentBackendUser && currentBackendUser.eaInvited" />
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">Sync</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
These settings are synced to cloud.
|
||||
</div>
|
||||
@@ -87,15 +88,12 @@
|
||||
</SmartToggle>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset v-if="currentBackendUser && currentBackendUser.eaInvited">
|
||||
<Teams />
|
||||
</fieldset>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||
<div class="md:grid md:gap-4 md:grid-cols-3">
|
||||
<div class="p-8 md:col-span-1">
|
||||
<h3 class="heading">
|
||||
{{ $t("theme") }}
|
||||
@@ -105,10 +103,10 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="space-y-8 p-8 md:col-span-2">
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("background") }}
|
||||
</legend>
|
||||
</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
<ColorScheme placeholder="..." tag="span">
|
||||
{{
|
||||
@@ -123,30 +121,30 @@
|
||||
<div class="mt-4">
|
||||
<SmartColorModePicker />
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
</section>
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("color") }}
|
||||
</legend>
|
||||
</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
{{ active.charAt(0).toUpperCase() + active.slice(1) }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<SmartAccentModePicker />
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
</section>
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("choose_language") }}
|
||||
</legend>
|
||||
</h4>
|
||||
<div class="mt-4">
|
||||
<SmartChangeLanguage />
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
</section>
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("experiments") }}
|
||||
</legend>
|
||||
</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
{{ $t("experiments_notice") }}
|
||||
<SmartLink
|
||||
@@ -205,11 +203,11 @@
|
||||
</SmartToggle>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md:grid md:grid-cols-3 md:gap-4">
|
||||
<div class="md:grid md:gap-4 md:grid-cols-3">
|
||||
<div class="p-8 md:col-span-1">
|
||||
<h3 class="heading">
|
||||
{{ $t("settings.interceptor") }}
|
||||
@@ -219,10 +217,10 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="space-y-8 p-8 md:col-span-2">
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("extensions") }}
|
||||
</legend>
|
||||
</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
<span v-if="extensionVersion != null">
|
||||
{{
|
||||
@@ -266,11 +264,11 @@
|
||||
</SmartToggle>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="font-bold text-secondaryDark">
|
||||
</section>
|
||||
<section>
|
||||
<h4 class="font-bold text-secondaryDark">
|
||||
{{ $t("proxy") }}
|
||||
</legend>
|
||||
</h4>
|
||||
<div class="mt-1 text-secondaryLight">
|
||||
{{ `${$t("official_proxy_hosting")} ${$t("read_the")}` }}
|
||||
<SmartLink
|
||||
@@ -315,7 +313,7 @@
|
||||
py-2
|
||||
px-4
|
||||
block
|
||||
focus:outline-none focus:border-accent
|
||||
focus:border-accent focus:outline-none
|
||||
"
|
||||
type="url"
|
||||
:disabled="!PROXY_ENABLED"
|
||||
@@ -330,7 +328,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -22,6 +22,7 @@ export default defineConfig({
|
||||
dividerDark: "var(--divider-dark-color)",
|
||||
error: "var(--error-color)",
|
||||
tooltip: "var(--tooltip-color)",
|
||||
popover: "var(--popover-color)",
|
||||
gradientFrom: "var(--gradient-from-color)",
|
||||
gradientVia: "var(--gradient-via-color)",
|
||||
gradientTo: "var(--gradient-to-color)",
|
||||
|
||||
Reference in New Issue
Block a user