Browse Source

Merge pull request #269 from wingkwong/feat/i18n

feat: add i18n to ProjectTreeView & SpreadsheetNavDrawer
pull/272/head
Pranav C 3 years ago committed by GitHub
parent
commit
949fa15b7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1027
      packages/nc-gui/components/ProjectTreeView.vue
  2. 518
      packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
  3. 36
      packages/nc-gui/static/lang/en.json
  4. 36
      packages/nc-gui/static/lang/ja.json
  5. 36
      packages/nc-gui/static/lang/zh.json

1027
packages/nc-gui/components/ProjectTreeView.vue

File diff suppressed because it is too large Load Diff

518
packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue

@ -2,49 +2,55 @@
<v-navigation-drawer <v-navigation-drawer
class="views-navigation-drawer" class="views-navigation-drawer"
:style="{ :style="{
maxWidth:toggleDrawer ? '0': '220px', maxWidth: toggleDrawer ? '0' : '220px',
minWidth:toggleDrawer ? '0': '220px' minWidth: toggleDrawer ? '0' : '220px',
}"> }"
>
<v-container fluid class="h-100 py-0"> <v-container fluid class="h-100 py-0">
<div class="d-flex flex-column h-100"> <div class="d-flex flex-column h-100">
<div class="flex-grow-1" style="overflow: auto; min-height: 350px">
<div class="flex-grow-1" style="overflow: auto; min-height:350px">
<v-list dense> <v-list dense>
<v-list-item dense> <v-list-item dense>
<span class="body-2 grey--text">Views</span> <!-- Views -->
<span class="body-2 grey--text">{{ $t('nav_drawer.title') }}</span>
</v-list-item> </v-list-item>
<v-list-item-group <v-list-item-group v-model="selectedViewIdLocal" color="primary">
v-model="selectedViewIdLocal" <v-list-item
color="primary" dense
> v-for="(view, i) in viewsList"
:key="i"
<v-list-item dense v-for="(view,i) in viewsList" :value="view.id"
:key="i" active-class="x-active--text"
:value="view.id" class="body-2 text-capitalize view"
active-class="x-active--text" >
class="body-2 text-capitalize view">
<v-list-item-icon class="mr-n1"> <v-list-item-icon class="mr-n1">
<v-icon color="primary" x-small v-if="viewIcons[view.show_as]" <v-icon
:color="viewIcons[view.show_as].color">{{ viewIcons[view.show_as].icon }} color="primary"
x-small
v-if="viewIcons[view.show_as]"
:color="viewIcons[view.show_as].color"
>{{ viewIcons[view.show_as].icon }}
</v-icon> </v-icon>
<v-icon color="primary" small v-else>mdi-table</v-icon> <v-icon color="primary" small v-else>mdi-table</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title> <v-list-item-title>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<div class="font-weight-regular" style="overflow: hidden; text-overflow: ellipsis"> <div
class="font-weight-regular"
style="overflow: hidden; text-overflow: ellipsis"
>
<input <input
:ref="`input${i}`" :ref="`input${i}`"
v-model="view.title" v-model="view.title"
@click.stop v-if="view.edit" @click.stop
v-if="view.edit"
@keydown.enter.stop="updateViewName(view)" @keydown.enter.stop="updateViewName(view)"
@blur="updateViewName(view)" @blur="updateViewName(view)"
/>
<template v-else
><span v-on="on">{{ view.alias || view.title }}</span></template
> >
<template
v-else
><span v-on="on">{{ view.alias || view.title }}</span></template>
</div> </div>
</template> </template>
{{ view.alias || view.title }} {{ view.alias || view.title }}
@ -52,140 +58,206 @@
</v-list-item-title> </v-list-item-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<template v-if="_isUIAllowed('virtualViewsCreateOrEdit')"> <template v-if="_isUIAllowed('virtualViewsCreateOrEdit')">
<x-icon v-if="view.type === 'vtable' && !view.edit" <!-- Copy view -->
tooltip="Copy view" <x-icon
x-small color="primary" v-if="view.type === 'vtable' && !view.edit"
@click.stop="copyView(view,i)" v-bind:tooltip="$t('nav_drawer.virtual_views.action.copy')"
iconClass="view-icon"> x-small
color="primary"
@click.stop="copyView(view, i)"
iconClass="view-icon"
>
mdi-content-copy mdi-content-copy
</x-icon> </x-icon>
<x-icon v-if="view.type === 'vtable' && !view.edit" <!-- Rename view -->
tooltip="Rename view" <x-icon
x-small color="primary" v-if="view.type === 'vtable' && !view.edit"
@click.stop="showRenameTextBox(view,i)" v-bind:tooltip="$t('nav_drawer.virtual_views.action.rename')"
iconClass="view-icon"> x-small
color="primary"
@click.stop="showRenameTextBox(view, i)"
iconClass="view-icon"
>
mdi-pencil mdi-pencil
</x-icon> </x-icon>
<x-icon v-if="view.type === 'vtable'" <!-- Delete view" -->
tooltip="Delete view" <x-icon
small color="error" @click.stop="deleteView(view)" v-if="view.type === 'vtable'"
iconClass="view-icon"> v-bind:tooltip="$t('nav_drawer.virtual_views.action.delete')"
small
color="error"
@click.stop="deleteView(view)"
iconClass="view-icon"
>
mdi-delete-outline mdi-delete-outline
</x-icon> </x-icon>
</template> </template>
<v-icon v-if="view.id === selectedViewId" small class="check-icon">mdi-check-bold</v-icon> <v-icon v-if="view.id === selectedViewId" small class="check-icon"
>mdi-check-bold</v-icon
>
</v-list-item> </v-list-item>
</v-list-item-group> </v-list-item-group>
</v-list> </v-list>
<template v-if="hideViews && _isUIAllowed('virtualViewsCreateOrEdit')"> <template v-if="hideViews && _isUIAllowed('virtualViewsCreateOrEdit')">
<v-divider class="advance-menu-divider"> <v-divider class="advance-menu-divider"> </v-divider>
</v-divider>
<v-list dense :class="{ <v-list
'advanced-border' : overShieldIcon dense
}"> :class="{
'advanced-border': overShieldIcon,
}"
>
<v-list-item dense> <v-list-item dense>
<span class="body-2 grey--text" @dblclick="enableDummyFeat = true">Create a View</span> <!-- Create a View -->
<span class="body-2 grey--text" @dblclick="enableDummyFeat = true">
{{ $t('nav_drawer.virtual_views.title') }}
</span>
<v-tooltip top> <v-tooltip top>
<template v-slot:activator="{ on }">
<template v-slot:activator="{on}"> <x-icon
<x-icon v-on="on" color="pink grey" v-on="on"
@mouseenter="overShieldIcon = true" color="pink grey"
@mouseleave="overShieldIcon = false" @mouseenter="overShieldIcon = true"
icon-class="ml-2" small>mdi-shield-lock-outline @mouseleave="overShieldIcon = false"
icon-class="ml-2"
small
>mdi-shield-lock-outline
</x-icon> </x-icon>
</template> </template>
<span class="caption">Only visible to Creator</span> <!-- Only visible to Creator -->
<span class="caption">
{{ $t('nav_drawer.virtual_views.caption') }}
</span>
</v-tooltip> </v-tooltip>
</v-list-item> </v-list-item>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-list-item v-on="on" dense @click="openCreateViewDlg('grid')" <v-list-item v-on="on" dense @click="openCreateViewDlg('grid')" class="body-2">
class="body-2">
<v-list-item-icon class="mr-n1"> <v-list-item-icon class="mr-n1">
<v-icon color="blue" x-small>mdi-grid-large</v-icon> <v-icon color="blue" x-small>mdi-grid-large</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title><span class="font-weight-regular">Grid</span></v-list-item-title> <v-list-item-title
><span class="font-weight-regular">
<!-- Grid -->
{{ $t('nav_drawer.virtual_views.grid') }}
</span></v-list-item-title
>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-icon class="mr-1" small>mdi-plus</v-icon> <v-icon class="mr-1" small>mdi-plus</v-icon>
</v-list-item> </v-list-item>
</template> </template>
Add Grid View <!-- Add Grid View -->
{{ $t('nav_drawer.virtual_views.grid.create') }}
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-list-item v-on="on" dense @click="openCreateViewDlg('gallery')" <v-list-item v-on="on" dense @click="openCreateViewDlg('gallery')" class="body-2">
class="body-2">
<v-list-item-icon class="mr-n1"> <v-list-item-icon class="mr-n1">
<v-icon color="orange" x-small>mdi-camera-image</v-icon> <v-icon color="orange" x-small>mdi-camera-image</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title><span class="font-weight-regular">Gallery</span></v-list-item-title> <v-list-item-title
><span class="font-weight-regular">
<!-- Gallery -->
{{ $t('nav_drawer.virtual_views.gallery') }}
</span></v-list-item-title
>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-icon class="mr-1" small>mdi-plus</v-icon> <v-icon class="mr-1" small>mdi-plus</v-icon>
</v-list-item> </v-list-item>
</template> </template>
Add Gallery View <!-- Add Gallery View -->
{{ $t('nav_drawer.virtual_views.gallery.create') }}
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-list-item v-on="on" dense @click="enableDummyFeat ? openCreateViewDlg('calendar') : comingSoon()" <v-list-item
class="body-2"> v-on="on"
dense
@click="enableDummyFeat ? openCreateViewDlg('calendar') : comingSoon()"
class="body-2"
>
<v-list-item-icon class="mr-n1"> <v-list-item-icon class="mr-n1">
<v-icon x-small>mdi-calendar</v-icon> <v-icon x-small>mdi-calendar</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title><span class="font-weight-regular">Calendar</span></v-list-item-title> <v-list-item-title
><span class="font-weight-regular">
<!-- Calendar -->
{{ $t('nav_drawer.virtual_views.calendar') }}
</span></v-list-item-title
>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-icon class="mr-1" small>mdi-plus</v-icon> <v-icon class="mr-1" small>mdi-plus</v-icon>
</v-list-item> </v-list-item>
</template> </template>
Add Calendar View <!-- Add Calendar View -->
{{ $t('nav_drawer.virtual_views.calendar.create') }}
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-list-item v-on="on" dense @click="enableDummyFeat ? openCreateViewDlg('kanban') : comingSoon()" <v-list-item
openClass="body-2"> v-on="on"
dense
@click="enableDummyFeat ? openCreateViewDlg('kanban') : comingSoon()"
openClass="body-2"
>
<v-list-item-icon class="mr-n1"> <v-list-item-icon class="mr-n1">
<v-icon x-small>mdi-tablet-dashboard</v-icon> <v-icon x-small>mdi-tablet-dashboard</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title><span class="font-weight-regular">Kanban</span></v-list-item-title> <v-list-item-title
><span class="font-weight-regular">
<!-- Kanban -->
{{ $t('nav_drawer.virtual_views.kanban') }}
</span></v-list-item-title
>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-icon class="mr-1" small>mdi-plus</v-icon> <v-icon class="mr-1" small>mdi-plus</v-icon>
</v-list-item> </v-list-item>
</template> </template>
Add Kanban View <!-- Add Kanban View -->
{{ $t('nav_drawer.virtual_views.kanban.create') }}
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-list-item v-on="on" dense @click="$toast.info('Coming soon').goAway(3000)" <v-list-item
class="body-2"> v-on="on"
dense
@click="$toast.info('Coming soon').goAway(3000)"
class="body-2"
>
<v-list-item-icon class="mr-n1"> <v-list-item-icon class="mr-n1">
<v-icon x-small class="mt-n1">mdi-form-select</v-icon> <v-icon x-small class="mt-n1">mdi-form-select</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title><span class="font-weight-regular">Form</span></v-list-item-title> <v-list-item-title
><span class="font-weight-regular">
<!-- Form -->
{{ $t('nav_drawer.virtual_views.form') }}
</span></v-list-item-title
>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-icon class="mr-1" small>mdi-plus</v-icon> <v-icon class="mr-1" small>mdi-plus</v-icon>
</v-list-item> </v-list-item>
</template> </template>
Add Form View <!-- Add Form View -->
{{ $t('nav_drawer.virtual_views.form.create') }}
</v-tooltip> </v-tooltip>
</v-list> </v-list>
</template> </template>
</div> </div>
<div class="pa-2 sponsor-wrapper" v-if="(time - $store.state.windows.miniSponsorCard) > (15 * 60 * 1000) "> <div
<v-icon small class="close-icon" @click="hideMiniSponsorCard">mdi-close-circle-outline</v-icon> class="pa-2 sponsor-wrapper"
v-if="time - $store.state.windows.miniSponsorCard > 15 * 60 * 1000"
>
<v-icon small class="close-icon" @click="hideMiniSponsorCard"
>mdi-close-circle-outline</v-icon
>
<sponsor-mini :nav="true"></sponsor-mini> <sponsor-mini :nav="true"></sponsor-mini>
</div> </div>
<!--<div class="text-center"> <!--<div class="text-center">
@ -203,22 +275,34 @@
--> -->
<div v-if="_isUIAllowed('table-advanced')"> <div v-if="_isUIAllowed('table-advanced')">
<v-divider></v-divider> <v-divider></v-divider>
<v-list dense :class="{ <v-list
'advanced-border' : overAdvShieldIcon dense
}"> :class="{
'advanced-border': overAdvShieldIcon,
}"
>
<v-list-item dense> <v-list-item dense>
<span class="body-2 grey--text" @dblclick="$emit('update:showAdvanceOptions', !showAdvanceOptions)">Advanced</span> <span
class="body-2 grey--text"
@dblclick="$emit('update:showAdvanceOptions', !showAdvanceOptions)"
>Advanced</span
>
<v-tooltip top> <v-tooltip top>
<template v-slot:activator="{ on }">
<template v-slot:activator="{on}"> <x-icon
<x-icon v-on="on" color="pink grey" v-on="on"
@mouseenter="overAdvShieldIcon = true" color="pink grey"
@mouseleave="overAdvShieldIcon = false" @mouseenter="overAdvShieldIcon = true"
icon-class="ml-2" small>mdi-shield-lock-outline @mouseleave="overAdvShieldIcon = false"
icon-class="ml-2"
small
>mdi-shield-lock-outline
</x-icon> </x-icon>
</template> </template>
<span class="caption">Only visible to Creator</span> <span class="caption">
<!-- Only visible to Creator -->
{{ $t('nav_drawer.virtual_views.caption') }}
</span>
</v-tooltip> </v-tooltip>
</v-list-item> </v-list-item>
<!-- <v-tooltip bottom>--> <!-- <v-tooltip bottom>-->
@ -226,21 +310,29 @@
<!-- <v-menu offset-x left>--> <!-- <v-menu offset-x left>-->
<!-- <template v-slot:activator="{on}">--> <!-- <template v-slot:activator="{on}">-->
<v-list-item <v-list-item
v-show="selectedView && (selectedView.type === 'view' || selectedView.type === 'table')" v-show="
selectedView && (selectedView.type === 'view' || selectedView.type === 'table')
"
v-if="_isUIAllowed('shareview')" v-if="_isUIAllowed('shareview')"
@click="genShareLink" @click="genShareLink"
> >
<v-icon x-small class="mr-2">mdi-open-in-new</v-icon> <v-icon x-small class="mr-2">mdi-open-in-new</v-icon>
<span class="caption"> Share View</span> <span class="caption">
<!-- Share View -->
{{ $t('nav_drawer.advanced.title1') }}
</span>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-menu offset-y> <v-menu offset-y>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-icon small @click.stop v-on="on">mdi-dots-vertical</v-icon> <v-icon small @click.stop v-on="on">mdi-dots-vertical</v-icon>
</template> </template>
<v-list dense> <v-list dense>
<v-list-item dense @click="$emit('showAdditionalFeatOverlay','shared-views')"> <v-list-item dense @click="$emit('showAdditionalFeatOverlay', 'shared-views')">
<v-list-item-title> <v-list-item-title>
<span class="font-weight-regular">Views List</span> <span class="font-weight-regular">
<!-- Views List -->
{{ $t('nav_drawer.advanced.option1') }}
</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
</v-list> </v-list>
@ -270,29 +362,25 @@
<!-- </v-tooltip>--> <!-- </v-tooltip>-->
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{on}"> <template v-slot:activator="{ on }">
<v-list-item v-on="on" <v-list-item v-on="on" @click="copyapiUrlToClipboard">
@click="copyapiUrlToClipboard">
<v-icon x-small class="mr-2">mdi-content-copy</v-icon> <v-icon x-small class="mr-2">mdi-content-copy</v-icon>
<span class="caption"> Copy API URL</span> <!-- Copy API URL -->
<span class="caption">{{ $t('nav_drawer.advanced.option1') }}</span>
</v-list-item> </v-list-item>
</template> </template>
Copy API URL <!-- Copy API URL -->
{{ $t('nav_drawer.advanced.option1') }}
</v-tooltip> </v-tooltip>
<template <template v-if="_isUIAllowed('model')">
v-if="_isUIAllowed('model')">
<v-divider class="advance-menu-divider"></v-divider> <v-divider class="advance-menu-divider"></v-divider>
<slot></slot> <slot></slot>
</template> </template>
</v-list> </v-list>
</div> </div>
</div> </div>
</v-container> </v-container>
<create-view-dialog <create-view-dialog
v-if="showCreateView" v-if="showCreateView"
:nodes="nodes" :nodes="nodes"
@ -307,33 +395,37 @@
:alias="meta._tn" :alias="meta._tn"
></create-view-dialog> ></create-view-dialog>
<v-dialog v-model="showShareModel" max-width="650px">
<v-dialog v-model="showShareModel"
max-width="650px"
>
<v-card class="pa-3 backgroundColor"> <v-card class="pa-3 backgroundColor">
<v-container @click.stop> <v-container @click.stop>
<h3 class="title mb-3">This view is shared via a private link</h3> <h3 class="title mb-3">
<p class="grey&#45;&#45;text body-2">People with private link can only see cells visible in this view</p> <!-- This view is shared via a private link -->
<div style="border-radius: 4px" {{ $t('nav_drawer.share_view.title') }}
class="share-link-box body-2 pa-2 d-flex align-center"> </h3>
<p class="grey&#45;&#45;text body-2">
<!-- People with private link can only see cells visible in this view -->
</p>
<div style="border-radius: 4px" class="share-link-box body-2 pa-2 d-flex align-center">
{{ shareLink.url }} {{ shareLink.url }}
<v-spacer> <v-spacer> </v-spacer>
</v-spacer>
<a :href="shareLink.url" style="text-decoration: none" target="_blank"> <a :href="shareLink.url" style="text-decoration: none" target="_blank">
<v-icon small class="mx-2">mdi-open-in-new</v-icon> <v-icon small class="mx-2">mdi-open-in-new</v-icon>
</a> </a>
<v-icon small <v-icon small class="pointer" @click="copyShareUrlToClipboard"
class="pointer" >mdi-content-copy
@click="copyShareUrlToClipboard"
>mdi-content-copy
</v-icon> </v-icon>
</div> </div>
<v-switch dense v-model="passwordProtect" @change="onPasswordProtectChange"> <v-switch dense v-model="passwordProtect" @change="onPasswordProtectChange">
<template v-slot:label> <template v-slot:label>
<span class="caption" v-show="!passwordProtect">Restrict access with a password</span> <!-- Restrict access with a password -->
<span class="caption" v-show="passwordProtect">Access is password restricted</span> <span class="caption" v-show="!passwordProtect">
{{ $t('nav_drawer.share_view.toggle.option1') }}
</span>
<!-- Access is password restricted -->
<span class="caption" v-show="passwordProtect">
{{ $t('nav_drawer.share_view.toggle.option2') }}
</span>
</template> </template>
</v-switch> </v-switch>
@ -342,44 +434,45 @@
browser-autocomplete="new-password" browser-autocomplete="new-password"
class="password-field mr-2 caption" class="password-field mr-2 caption"
style="max-width: 230px" style="max-width: 230px"
:type="showShareLinkPassword ? 'text' : 'password'" :type="showShareLinkPassword ? 'text' : 'password'"
hint="Enter the password" v-bind:hint="$t('nav_drawer.share_view.password.caption')"
persistent-hint persistent-hint
dense dense
v-model="shareLink.password" v-model="shareLink.password"
solo solo
flat> flat
>
<template v-slot:append> <template v-slot:append>
<v-icon small @click="showShareLinkPassword = !showShareLinkPassword"> <v-icon small @click="showShareLinkPassword = !showShareLinkPassword">
{{ showShareLinkPassword ? 'visibility_off' : 'visibility' }} {{ showShareLinkPassword ? 'visibility_off' : 'visibility' }}
</v-icon> </v-icon>
</template> </template>
</v-text-field> </v-text-field>
<v-btn color="primary" class="caption" small @click="saveShareLinkPassword">Save password</v-btn> <v-btn color="primary" class="caption" small @click="saveShareLinkPassword">
<!-- Save password -->
{{ $t('nav_drawer.share_view.password.button') }}
</v-btn>
</div> </div>
</v-container> </v-container>
</v-card> </v-card>
</v-dialog> </v-dialog>
</v-navigation-drawer> </v-navigation-drawer>
</template> </template>
<script> <script>
import CreateViewDialog from "@/components/project/spreadsheet/dialog/createViewDialog"; import CreateViewDialog from '@/components/project/spreadsheet/dialog/createViewDialog';
import SponsorMini from "@/components/sponsorMini"; import SponsorMini from '@/components/sponsorMini';
export default { export default {
name: "spreadsheetNavDrawer", name: 'spreadsheetNavDrawer',
components: {SponsorMini, CreateViewDialog}, components: { SponsorMini, CreateViewDialog },
props: { props: {
showAdvanceOptions: Boolean, showAdvanceOptions: Boolean,
hideViews: Boolean, hideViews: Boolean,
primaryValueColumn: [Number, String], primaryValueColumn: [Number, String],
toggleDrawer: { toggleDrawer: {
type: Boolean, type: Boolean,
default: false default: false,
}, },
nodes: Object, nodes: Object,
table: String, table: String,
@ -393,7 +486,7 @@ export default {
sortList: [Object, Array], sortList: [Object, Array],
load: { load: {
default: true, default: true,
type: Boolean type: Boolean,
}, },
currentApiUrl: String, currentApiUrl: String,
fieldsOrder: Array, fieldsOrder: Array,
@ -412,11 +505,11 @@ export default {
overShieldIcon: false, overShieldIcon: false,
viewsList: [], viewsList: [],
viewIcons: { viewIcons: {
grid: {icon: 'mdi-grid-large', color: 'blue'}, grid: { icon: 'mdi-grid-large', color: 'blue' },
form: {icon: 'mdi-form-select', color: 'pink'}, form: { icon: 'mdi-form-select', color: 'pink' },
calendar: {icon: 'mdi-calendar', color: 'purple'}, calendar: { icon: 'mdi-calendar', color: 'purple' },
gallery: {icon: 'mdi-camera-image', color: 'orange'}, gallery: { icon: 'mdi-camera-image', color: 'orange' },
kanban: {icon: 'mdi-tablet-dashboard', color: 'green'}, kanban: { icon: 'mdi-tablet-dashboard', color: 'green' },
}, },
copyViewRef: null, copyViewRef: null,
shareLink: {}, shareLink: {},
@ -432,9 +525,10 @@ export default {
selectedViewIdLocal: { selectedViewIdLocal: {
get() { get() {
return this.selectedViewId; return this.selectedViewId;
}, set(id) { },
set(id) {
const selectedView = this.viewsList && this.viewsList.find(v => v.id === id); const selectedView = this.viewsList && this.viewsList.find(v => v.id === id);
let query_params = {} let query_params = {};
this.$emit('update:selectedViewId', id); this.$emit('update:selectedViewId', id);
this.$emit('update:selectedView', selectedView); this.$emit('update:selectedView', selectedView);
@ -457,15 +551,15 @@ export default {
this.$emit('mapFieldsAndShowFields'); this.$emit('mapFieldsAndShowFields');
} }
this.$emit('loadTableData'); this.$emit('loadTableData');
} },
} },
}, },
watch: { watch: {
async load(v) { async load(v) {
if (v) { if (v) {
await this.loadViews(); await this.loadViews();
} }
} },
}, },
methods: { methods: {
hideMiniSponsorCard() { hideMiniSponsorCard() {
@ -476,7 +570,8 @@ export default {
this.showCreateView = true; this.showCreateView = true;
}, },
isCentrallyAligned(col) { isCentrallyAligned(col) {
return !['SingleLineText', return ![
'SingleLineText',
'LongText', 'LongText',
'Attachment', 'Attachment',
'Date', 'Date',
@ -485,31 +580,40 @@ export default {
'URL', 'URL',
'DateTime', 'DateTime',
'CreateTime', 'CreateTime',
'LastModifiedTime'].includes(col.uidt) 'LastModifiedTime',
].includes(col.uidt);
}, },
onPasswordProtectChange() { onPasswordProtectChange() {
if (!this.passwordProtect) { if (!this.passwordProtect) {
this.shareLink.password = null; this.shareLink.password = null;
this.saveShareLinkPassword() this.saveShareLinkPassword();
} }
}, },
async saveShareLinkPassword() { async saveShareLinkPassword() {
try { try {
await this.$store.dispatch('sqlMgr/ActSqlOp', [{dbAlias: this.nodes.dbAlias}, 'updateSharedViewLinkPassword', { await this.$store.dispatch('sqlMgr/ActSqlOp', [
id: this.shareLink.id, { dbAlias: this.nodes.dbAlias },
password: this.shareLink.password 'updateSharedViewLinkPassword',
}]); {
id: this.shareLink.id,
password: this.shareLink.password,
},
]);
this.$toast.success('Successfully updated').goAway(3000); this.$toast.success('Successfully updated').goAway(3000);
} catch (e) { } catch (e) {
this.$toast.error(e.message).goAway(3000); this.$toast.error(e.message).goAway(3000);
} }
}, },
async loadViews() { async loadViews() {
this.viewsList = await this.sqlOp({ this.viewsList = await this.sqlOp(
dbAlias: this.nodes.dbAlias {
}, 'xcVirtualTableList', { dbAlias: this.nodes.dbAlias,
tn: this.table },
}); 'xcVirtualTableList',
{
tn: this.table,
}
);
this.selectedViewIdLocal = this.viewsList && this.viewsList[0] && this.viewsList[0].id; this.selectedViewIdLocal = this.viewsList && this.viewsList[0] && this.viewsList[0].id;
}, },
// async onViewChange() { // async onViewChange() {
@ -530,15 +634,16 @@ export default {
// this.$emit('loadTableData'); // this.$emit('loadTableData');
// }, // },
copyapiUrlToClipboard() { copyapiUrlToClipboard() {
this.$clipboard(this.currentApiUrl) this.$clipboard(this.currentApiUrl);
this.clipboardSuccessHandler() this.clipboardSuccessHandler();
}, async updateViewName(view) { },
async updateViewName(view) {
try { try {
await this.sqlOp({dbAlias: this.nodes.dbAlias}, 'xcVirtualTableRename', { await this.sqlOp({ dbAlias: this.nodes.dbAlias }, 'xcVirtualTableRename', {
id: view.id, id: view.id,
title: view.title, title: view.title,
alias: view.alias, alias: view.alias,
parent_model_title: this.meta._tn parent_model_title: this.meta._tn,
}); });
this.$toast.success('View renamed successfully').goAway(3000); this.$toast.success('View renamed successfully').goAway(3000);
} catch (e) { } catch (e) {
@ -551,39 +656,48 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
const input = this.$refs[`input${i}`][0]; const input = this.$refs[`input${i}`][0];
input.focus(); input.focus();
input.setSelectionRange(0, input.value.length) input.setSelectionRange(0, input.value.length);
}); });
}, async deleteView(view) { },
async deleteView(view) {
try { try {
await this.sqlOp({dbAlias: this.nodes.dbAlias}, 'xcVirtualTableDelete', { await this.sqlOp({ dbAlias: this.nodes.dbAlias }, 'xcVirtualTableDelete', {
id: view.id, id: view.id,
title: view.alias || view.title, title: view.alias || view.title,
parent_model_title: this.table parent_model_title: this.table,
}); });
this.$toast.success('View deleted successfully').goAway(3000); this.$toast.success('View deleted successfully').goAway(3000);
await this.loadViews(); await this.loadViews();
} catch (e) { } catch (e) {
this.$toast.error(e.message).goAway(3000); this.$toast.error(e.message).goAway(3000);
} }
}, async genShareLink() { },
async genShareLink() {
this.showShareModel = true; this.showShareModel = true;
const sharedViewUrl = await this.$store.dispatch('sqlMgr/ActSqlOp', [{dbAlias: this.nodes.dbAlias}, 'createSharedViewLink', { const sharedViewUrl = await this.$store.dispatch('sqlMgr/ActSqlOp', [
model_name: this.table, { dbAlias: this.nodes.dbAlias },
meta: this.meta, 'createSharedViewLink',
query_params: { {
where: this.concatenatedXWhere, model_name: this.table,
sort: this.sort, meta: this.meta,
fields: Object.keys(this.showFields).filter(f => this.showFields[f]).join(',') query_params: {
where: this.concatenatedXWhere,
sort: this.sort,
fields: Object.keys(this.showFields)
.filter(f => this.showFields[f])
.join(','),
},
password: this.sharedViewPassword,
}, },
password: this.sharedViewPassword ]);
}])
this.shareLink = sharedViewUrl; this.shareLink = sharedViewUrl;
}, },
copyView(view, i) { copyView(view, i) {
this.createViewType = view.show_as; this.createViewType = view.show_as;
this.showCreateView = true; this.showCreateView = true;
this.copyViewRef = view; this.copyViewRef = view;
}, async onViewCreate(viewMeta) { },
async onViewCreate(viewMeta) {
this.copyViewRef = null; this.copyViewRef = null;
await this.loadViews(); await this.loadViews();
this.selectedViewIdLocal = viewMeta.id; this.selectedViewIdLocal = viewMeta.id;
@ -599,26 +713,26 @@ export default {
document.body.removeChild(el); document.body.removeChild(el);
}, },
clipboardSuccessHandler() { clipboardSuccessHandler() {
this.$toast.info('Copied to clipboard').goAway(1000) this.$toast.info('Copied to clipboard').goAway(1000);
}, },
copyShareUrlToClipboard() { copyShareUrlToClipboard() {
this.clipboard(this.shareLink.url) this.clipboard(this.shareLink.url);
this.clipboardSuccessHandler() this.clipboardSuccessHandler();
}, },
},
} };
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
::v-deep { ::v-deep {
.v-list-item--dense .v-list-item__icon, .v-list--dense .v-list-item .v-list-item__icon { .v-list-item--dense .v-list-item__icon,
.v-list--dense .v-list-item .v-list-item__icon {
margin-top: 4px; margin-top: 4px;
margin-bottom: 4px; margin-bottom: 4px;
} }
.v-list-item--dense, .v-list--dense .v-list-item { .v-list-item--dense,
.v-list--dense .v-list-item {
min-height: 32px; min-height: 32px;
} }
@ -628,12 +742,11 @@ export default {
border-style: dashed; border-style: dashed;
margin-top: 5px; margin-top: 5px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.view .view-icon { .view .view-icon {
display: none; display: none;
transition: .3s display; transition: 0.3s display;
} }
.view:hover .view-icon { .view:hover .view-icon {
@ -650,7 +763,7 @@ export default {
.v-messages__message { .v-messages__message {
color: grey; color: grey;
font-size: .65rem; font-size: 0.65rem;
} }
} }
@ -672,8 +785,8 @@ export default {
bottom: 0; bottom: 0;
right: 0; right: 0;
background: var(--v-primary-base); background: var(--v-primary-base);
opacity: .2; opacity: 0.2;
content: ""; content: '';
z-index: 1; z-index: 1;
pointer-events: none; pointer-events: none;
} }
@ -682,7 +795,6 @@ export default {
border-left: 1px solid #80808033; border-left: 1px solid #80808033;
} }
.sponsor-wrapper { .sponsor-wrapper {
position: relative; position: relative;
@ -692,7 +804,7 @@ export default {
top: 10px; top: 10px;
z-index: 9; z-index: 9;
opacity: 0; opacity: 0;
transition: .4s opacity; transition: 0.4s opacity;
} }
&:hover .close-icon { &:hover .close-icon {

36
packages/nc-gui/static/lang/en.json

@ -78,5 +78,39 @@
"signin.head.title": "Log In | Noco", "signin.head.title": "Log In | Noco",
"signin.head.meta.hid": "Log In To Noco", "signin.head.meta.hid": "Log In To Noco",
"signin.head.meta.name": "Log In To Noco", "signin.head.meta.name": "Log In To Noco",
"signin.head.meta.content": "Log In To Noco" "signin.head.meta.content": "Log In To Noco",
"treeview.settings": "Settings",
"treeview.settings.tooltip": "Only visible to Creator",
"treeview.app_store": "App Store",
"treeview.team_n_auth": "Team & Auth",
"treeview.team_n_auth.tooltip": "Roles & Users Management",
"treeview.project_metadata": "Project Metadata",
"treeview.project_metadata.tooltip": "Meta Management",
"treeview.preview_as": "Preview as",
"treeview.reset_review": "Reset Preview",
"nav_drawer.title": "Views",
"nav_drawer.virtual_views.action.copy": "Copy view",
"nav_drawer.virtual_views.action.rename": "Rename view",
"nav_drawer.virtual_views.action.delete": "Delete view",
"nav_drawer.virtual_views.title": "Create a View",
"nav_drawer.virtual_views.caption": "Only visible to Creator",
"nav_drawer.virtual_views.grid": "Grid",
"nav_drawer.virtual_views.grid.create": "Add Grid View",
"nav_drawer.virtual_views.gallery": "Gallery",
"nav_drawer.virtual_views.gallery.create": "Add Gallery View",
"nav_drawer.virtual_views.calendar": "Calendar",
"nav_drawer.virtual_views.calendar.create": "Add Calendar View",
"nav_drawer.virtual_views.kanban": "Kanban",
"nav_drawer.virtual_views.kanban.create": "Add Kanban View",
"nav_drawer.virtual_views.form": "Form",
"nav_drawer.virtual_views.form.create": "Add Form View",
"nav_drawer.advanced.title1": "Share View",
"nav_drawer.advanced.option1": "Views List",
"nav_drawer.advanced.title2": "Copy API URL",
"nav_drawer.share_view.title": "This view is shared via a private link",
"nav_drawer.share_view.body": "People with private link can only see cells visible in this view",
"nav_drawer.share_view.toggle.option1": "Restrict access with a password",
"nav_drawer.share_view.toggle.option2": "Access is password restricted",
"nav_drawer.share_view.password.caption": "Enter the password",
"nav_drawer.share_view.password.button": "Save password"
} }

36
packages/nc-gui/static/lang/ja.json

@ -78,5 +78,39 @@
"signin.head.title": "Log In | Noco", "signin.head.title": "Log In | Noco",
"signin.head.meta.hid": "Log In To Noco", "signin.head.meta.hid": "Log In To Noco",
"signin.head.meta.name": "Log In To Noco", "signin.head.meta.name": "Log In To Noco",
"signin.head.meta.content": "Log In To Noco" "signin.head.meta.content": "Log In To Noco",
"treeview.settings": "Settings",
"treeview.settings.tooltip": "Only visible to Creator",
"treeview.app_store": "App Store",
"treeview.team_n_auth": "Team & Auth",
"treeview.team_n_auth.tooltip": "Roles & Users Management",
"treeview.project_metadata": "Project Metadata",
"treeview.project_metadata.tooltip": "Meta Management",
"treeview.preview_as": "Preview as",
"treeview.reset_review": "Reset Preview",
"nav_drawer.title": "Views",
"nav_drawer.virtual_views.action.copy": "Copy view",
"nav_drawer.virtual_views.action.rename": "Rename view",
"nav_drawer.virtual_views.action.delete": "Delete view",
"nav_drawer.virtual_views.title": "Create a View",
"nav_drawer.virtual_views.caption": "Only visible to Creator",
"nav_drawer.virtual_views.grid": "Grid",
"nav_drawer.virtual_views.grid.create": "Add Grid View",
"nav_drawer.virtual_views.gallery": "Gallery",
"nav_drawer.virtual_views.gallery.create": "Add Gallery View",
"nav_drawer.virtual_views.calendar": "Calendar",
"nav_drawer.virtual_views.calendar.create": "Add Calendar View",
"nav_drawer.virtual_views.kanban": "Kanban",
"nav_drawer.virtual_views.kanban.create": "Add Kanban View",
"nav_drawer.virtual_views.form": "Form",
"nav_drawer.virtual_views.form.create": "Add Form View",
"nav_drawer.advanced.title1": "Share View",
"nav_drawer.advanced.option1": "Views List",
"nav_drawer.advanced.title2": "Copy API URL",
"nav_drawer.share_view.title": "This view is shared via a private link",
"nav_drawer.share_view.body": "People with private link can only see cells visible in this view",
"nav_drawer.share_view.toggle.option1": "Restrict access with a password",
"nav_drawer.share_view.toggle.option2": "Access is password restricted",
"nav_drawer.share_view.password.caption": "Enter the password",
"nav_drawer.share_view.password.button": "Save password"
} }

36
packages/nc-gui/static/lang/zh.json

@ -78,6 +78,40 @@
"signin.head.title": "Log In | Noco", "signin.head.title": "Log In | Noco",
"signin.head.meta.hid": "Log In To Noco", "signin.head.meta.hid": "Log In To Noco",
"signin.head.meta.name": "Log In To Noco", "signin.head.meta.name": "Log In To Noco",
"signin.head.meta.content": "Log In To Noco" "signin.head.meta.content": "Log In To Noco",
"treeview.settings": "Settings",
"treeview.settings.tooltip": "Only visible to Creator",
"treeview.app_store": "App Store",
"treeview.team_n_auth": "Team & Auth",
"treeview.team_n_auth.tooltip": "Roles & Users Management",
"treeview.project_metadata": "Project Metadata",
"treeview.project_metadata.tooltip": "Meta Management",
"treeview.preview_as": "Preview as",
"treeview.reset_review": "Reset Preview",
"nav_drawer.title": "Views",
"nav_drawer.virtual_views.action.copy": "Copy view",
"nav_drawer.virtual_views.action.rename": "Rename view",
"nav_drawer.virtual_views.action.delete": "Delete view",
"nav_drawer.virtual_views.title": "Create a View",
"nav_drawer.virtual_views.caption": "Only visible to Creator",
"nav_drawer.virtual_views.grid": "Grid",
"nav_drawer.virtual_views.grid.create": "Add Grid View",
"nav_drawer.virtual_views.gallery": "Gallery",
"nav_drawer.virtual_views.gallery.create": "Add Gallery View",
"nav_drawer.virtual_views.calendar": "Calendar",
"nav_drawer.virtual_views.calendar.create": "Add Calendar View",
"nav_drawer.virtual_views.kanban": "Kanban",
"nav_drawer.virtual_views.kanban.create": "Add Kanban View",
"nav_drawer.virtual_views.form": "Form",
"nav_drawer.virtual_views.form.create": "Add Form View",
"nav_drawer.advanced.title1": "Share View",
"nav_drawer.advanced.option1": "Views List",
"nav_drawer.advanced.title2": "Copy API URL",
"nav_drawer.share_view.title": "This view is shared via a private link",
"nav_drawer.share_view.body": "People with private link can only see cells visible in this view",
"nav_drawer.share_view.toggle.option1": "Restrict access with a password",
"nav_drawer.share_view.toggle.option2": "Access is password restricted",
"nav_drawer.share_view.password.caption": "Enter the password",
"nav_drawer.share_view.password.button": "Save password"
} }
Loading…
Cancel
Save