Skip to content

Commit

Permalink
feat: add i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
yankeguo committed Feb 2, 2024
1 parent e539486 commit fa488b7
Show file tree
Hide file tree
Showing 17 changed files with 817 additions and 22 deletions.
51 changes: 50 additions & 1 deletion app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"encoding/hex"
"errors"
"net/http"
"sort"
"time"

"github.com/git-lfs/wildmatch"
"github.com/yankeguo/bunker/model"
"github.com/yankeguo/bunker/model/dao"
"github.com/yankeguo/halt"
Expand Down Expand Up @@ -403,10 +405,57 @@ func (a *App) routeDeleteGrant(c ufx.Context) {
c.JSON(map[string]any{})
}

func (a *App) routeGrantedItems(c ufx.Context) {
_, u := a.requireUser(c)

db := dao.Use(a.db)

grants := rg.Must(db.Grant.Where(db.Grant.UserID.Eq(u.ID)).Find())

servers := rg.Must(db.Server.Find())

type grantedItem struct {
ServerUser string `json:"server_user"`
ServerID string `json:"server_id"`
}

m := map[string][]string{}

for _, grant := range grants {
matcher := wildmatch.NewWildmatch(
grant.ServerID,
wildmatch.Basename,
wildmatch.CaseFold,
)

for _, server := range servers {
if matcher.Match(server.ID) {
m[server.ID] = append(m[server.ID], grant.ServerUser)
}
}
}

var grantedItems []grantedItem

for serverID, serverUsers := range m {
grantedItems = append(grantedItems, grantedItem{
ServerID: serverID,
ServerUser: serverUsers[0],
})
}

sort.SliceStable(grantedItems, func(i, j int) bool {
return grantedItems[i].ServerID < grantedItems[j].ServerID
})

c.JSON(map[string]any{"granted_items": grantedItems})
}

func InstallAppToRouter(a *App, ur ufx.Router) {
ur.HandleFunc("/backend/current_user", a.routeCurrentUser)
ur.HandleFunc("/backend/sign_in", a.routeSignIn)
ur.HandleFunc("/backend/sign_out", a.routeSignOut)
ur.HandleFunc("/backend/current_user", a.routeCurrentUser)
ur.HandleFunc("/backend/granted_items", a.routeGrantedItems)
ur.HandleFunc("/backend/keys", a.routeListKeys)
ur.HandleFunc("/backend/keys/create", a.routeCreateKey)
ur.HandleFunc("/backend/keys/delete", a.routeDeleteKey)
Expand Down
3 changes: 2 additions & 1 deletion ui/app.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<template>
<NuxtLoadingIndicator color="#0369a1" />
<UContainer>
<UContainer class="pb-32">
<NuxtLayout>
<NuxtPage></NuxtPage>
</NuxtLayout>
</UContainer>
<UNotifications />
<Footer></Footer>
</template>
51 changes: 51 additions & 0 deletions ui/components/footer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script setup lang="ts">
const year = new Date().getFullYear();
const colorMode = useColorMode();
const isDark = computed({
get() {
return colorMode.value === "dark";
},
set() {
colorMode.preference = colorMode.value === "dark" ? "light" : "dark";
},
});
function setLanguage(lang: string) {
document.cookie = `lang=${lang};path=/;max-age=31536000`;
location.reload();
}
</script>

<template>
<UContainer
class="fixed py-2 bottom-0 left-0 right-0 flex flex-row justify-between items-center bg-slate-100 dark:bg-slate-800">
<UButton to="https://github.com/yankeguo/bunker" target="_blank" variant="link" size="sm" color="black"
icon="i-simple-icons-github" label="yankeguo/bunker"></UButton>

<div class="flex flex-row items-center">
<ClientOnly>
<!-- i18n -->
<template v-for="(item, idx) in $langs">
<a @click.prevent="setLanguage(item)" :class="{
'text-sm': true,
underline: $lang === item,
'me-2': true,
}" href="#">
<span>{{ $langNames[item] }}</span>
</a>
<i class="i-bi-dot text-slate-400" />
</template>

<UButton :icon="isDark ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'
" size="2xs" color="black" variant="ghost" aria-label="Theme" :padded="false" @click="isDark = !isDark" />

<template #fallback>
<div class="w-8 h-8"></div>
</template>
</ClientOnly>
</div>

</UContainer>
</template>
5 changes: 3 additions & 2 deletions ui/components/skeleton/dashboard.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script setup lang="ts">
const { $t } = useNuxtApp()
const props = defineProps<{
titleName: string;
titleIcon: string;
Expand All @@ -11,14 +12,14 @@ const { data: user } = await useCurrentUser();
const links = [
[
{
label: "Dashboard",
label: $t("dashboard.title"),
icon: "i-mdi-view-dashboard",
to: { name: "dashboard" },
},
...(user.value.user?.is_admin
? [
{
label: "Servers",
label: $t("servers.title"),
icon: "i-mdi-server",
to: { name: "dashboard-servers" },
},
Expand Down
11 changes: 11 additions & 0 deletions ui/composables/granted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const useGrantedItems = () => {
return useAsyncData<{ granted_items: BGrantedItem[] }>(
"granted-items",
() => $fetch("/backend/granted_items"),
{
default() {
return { granted_items: [] };
},
}
);
};
2 changes: 1 addition & 1 deletion ui/composables/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useCurrentUser = async () => {

export const useUsers = () => {
return useAsyncData<{ users: BUser[] }>(
"servers",
"users",
() => $fetch("/backend/users"),
{
default() {
Expand Down
1 change: 1 addition & 0 deletions ui/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default defineNuxtConfig({
devtools: { enabled: true },
ssr: false,
modules: ["@nuxt/ui", "@vueuse/nuxt"],
plugins: ["~/plugins/i18n"],
ui: {
icons: ["heroicons", "simple-icons", "mdi", "noto-v1"],
},
Expand Down
51 changes: 47 additions & 4 deletions ui/pages/dashboard/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
<script setup lang="ts">
import type { FormError, FormSubmitEvent } from "#ui/types";
import { guardWorking } from "~/composables/error";
const { $t } = useNuxtApp()
definePageMeta({
middleware: ["auth"],
});
const { data: items, refresh: refreshItems } = await useGrantedItems();
const columns = [
{
key: "server_user",
label: $t('common.server_user'),
},
{
key: "server_id",
label: $t('common.server_id'),
},
{
key: 'example',
label: $t('dashboard.command_example')
}
];
function expandServerUser(s: string): string {
if (s === '*') {
return 'root'
}
return s
}
</script>
<template>
<SkeletonDashboard
title-name="Dashboard"
title-icon="i-mdi-view-dashboard"
></SkeletonDashboard>
<SkeletonDashboard :title-name="$t('dashboard.title')" title-icon="i-mdi-view-dashboard">
<template #left>
<UCard :ui="uiCard">
<p></p>
</UCard>
</template>
<UTable :rows="items.granted_items" :columns="columns">
<template #example-data="{ row }">
<code class="font-mono">ssh {{ expandServerUser(row.server_user) }}@{{ row.server_id }}@BUNKER_ADDRESS</code>
</template>
</UTable>
</SkeletonDashboard>
</template>
11 changes: 6 additions & 5 deletions ui/pages/dashboard/servers/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,25 +82,26 @@ async function deleteServer(id: string) {
</script>

<template>
<SkeletonDashboard title-name="Servers" title-icon="i-mdi-server">
<SkeletonDashboard :title-name="$t('servers.title')" title-icon="i-mdi-server">
<template #left>
<UCard :ui="uiCard">
<template #header>
<div class="flex flex-row items-center">
<UIcon name="i-mdi-server-plus" class="me-1"></UIcon>
<span>Add / Update Server</span>
<span>{{ $t('servers.add_update_server') }}</span>
</div>
</template>
<UForm :validate="validate" :state="state" class="space-y-4" @submit="onSubmit">
<UFormGroup label="Name" name="id">
<UFormGroup :label="$t('common.server_id')" name="id">
<UInput v-model="state.id" placeholder="Input server name" />
</UFormGroup>

<UFormGroup label="Address" name="address">
<UFormGroup :label="$t('common.server_address')" name="address">
<UInput v-model="state.address" placeholder="Input server address" />
</UFormGroup>

<UButton type="submit" icon="i-mdi-check-circle" label="Submit" :loading="!!working" :disabled="!!working">
<UButton type="submit" icon="i-mdi-check-circle" :label="$t('common.submit')" :loading="!!working"
:disabled="!!working">
</UButton>
</UForm>
</UCard>
Expand Down
13 changes: 5 additions & 8 deletions ui/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,22 @@ if (currentUser.value.user && currentUser.value.token) {
<template>
<div class="absolute top-0 left-0 w-full h-full flex flex-col justify-center items-center">
<div class="mb-12 text-center">
<div class="font-semibold font-mono text-4xl mb-6">Bunker System</div>
<UButton size="sm" icon="i-simple-icons-github" variant="link" to="https://github.com/yankeguo/bunker"
target="_blank" label="yankeguo/bunker"></UButton>
<div class="font-semibold text-4xl mb-6">Bunker System</div>
</div>

<UCard class="w-80">
<UForm :validate="validate" :state="state" class="space-y-4" @submit="onSubmit">
<UFormGroup label="Username" name="username">
<UFormGroup :label="$t('common.username')" name="username">
<UInput v-model="state.username" />
</UFormGroup>

<UFormGroup label="Password" name="password">
<UFormGroup :label="$t('common.password')" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>

<UButton type="submit" icon="i-mdi-login" :disabled="!!working" :loading="!!working">Sign In</UButton>
<UButton type="submit" icon="i-mdi-login" :disabled="!!working" :loading="!!working"
:label="$t('common.sign_in')"></UButton>
</UForm>
</UCard>

<div class="h-64"></div>
</div>
</template>
Loading

0 comments on commit fa488b7

Please sign in to comment.