-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: clean up table, add loading state, add no backup state
- Loading branch information
1 parent
3dbaa9c
commit 75ed672
Showing
1 changed file
with
218 additions
and
54 deletions.
There are no files selected for viewing
272 changes: 218 additions & 54 deletions
272
packages/extension/src/ui/action/views/settings/views/settings-backups/index.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,275 @@ | ||
<template> | ||
<div> | ||
<div class="settings-container"> | ||
<settings-inner-header v-bind="$attrs" :is-backups="true" /> | ||
|
||
<settings-switch | ||
title="Enable backups" | ||
:is-checked="isBackupsEnabled" | ||
@update:check="toggleBackups" | ||
/> | ||
|
||
<div class="settings__label"> | ||
<p> | ||
Backups are currently {{ isBackupsEnabled ? 'enabled' : 'disabled' }}. | ||
Backups are currently | ||
<strong>{{ isBackupsEnabled ? 'enabled' : 'disabled' }}</strong | ||
>. | ||
</p> | ||
</div> | ||
<p>Current Backups</p> | ||
<table> | ||
<thead> | ||
<tr> | ||
<th | ||
v-for="(header, i) in headers" | ||
:key="`${header}${i}`" | ||
class="header-item" | ||
> | ||
{{ header }} | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr | ||
v-for="entity in backups" | ||
:key="`entity-${entity.userId}`" | ||
class="table-rows" | ||
> | ||
<td>{{ entity.userId }}</td> | ||
<td>{{ entity.updatedAt }}</td> | ||
<td> | ||
{{ currentUserId === entity.userId ? 'true' : 'false' }} | ||
</td> | ||
<td> | ||
<settings-button | ||
style="max-width: 100px" | ||
title="delete" | ||
@click="deleteBackup(entity.userId)" | ||
/> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
|
||
<div v-if="isBackupsEnabled"> | ||
<div v-if="loading"> | ||
<div class="settings__backup-header">Loading backups</div> | ||
<table class="settings__backup-table"> | ||
<thead> | ||
<tr> | ||
<th v-for="(header, i) in headers" :key="`header-${i}`"> | ||
{{ header }} | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-one" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-one" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-two" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-two" /> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-one" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-one" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-two" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-two" /> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-one" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-one" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-two" /> | ||
</td> | ||
<td> | ||
<balance-loader class="settings__backup-table__loader-two" /> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
|
||
<div v-else-if="backups.length === 0"> | ||
<div class="settings__backup-header">No backups found</div> | ||
</div> | ||
|
||
<div v-else> | ||
<div class="settings__backup-header">Current backups</div> | ||
|
||
<table class="settings__backup-table"> | ||
<thead> | ||
<tr> | ||
<th v-for="(header, i) in headers" :key="`header-${i}`"> | ||
{{ header }} | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr | ||
v-for="(entity, index) in backups" | ||
:key="`entity-${entity.userId}-${index}`" | ||
> | ||
<td>{{ entity.userId }}</td> | ||
<td>{{ formatDate(entity.updatedAt) }}</td> | ||
<td> | ||
<span | ||
:class="[ | ||
'settings__backup-table__status-badge', | ||
entity.userId === currentUserId | ||
? 'settings__backup-table__status-active' | ||
: 'settings__backup-table__status-inactive', | ||
]" | ||
> | ||
{{ entity.userId === currentUserId ? 'Active' : 'Inactive' }} | ||
</span> | ||
</td> | ||
<td> | ||
<div | ||
class="settings__backup-table__action-button" | ||
@click="deleteBackup(entity.userId)" | ||
> | ||
<delete-icon /> | ||
</div> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { onMounted, ref } from 'vue'; | ||
import BackupState from '@/libs/backup-state'; | ||
import { ListBackupType } from '@/libs/backup-state/types'; | ||
import SettingsInnerHeader from '@action/views/settings/components/settings-inner-header.vue'; | ||
import SettingsSwitch from '@action/views/settings/components/settings-switch.vue'; | ||
import SettingsButton from '@action/views/settings/components/settings-button.vue'; | ||
import { onMounted, ref } from 'vue'; | ||
import deleteIcon from '@/ui/action/icons/actions/trash.vue'; | ||
import BalanceLoader from '@action/icons/common/balance-loader.vue'; | ||
const backupState = new BackupState(); | ||
const loading = ref(true); | ||
const isBackupsEnabled = ref(true); | ||
const currentUserId = ref(''); | ||
const backups = ref<ListBackupType[]>([]); | ||
const headers = ['userid', 'last updated', 'this', 'delete']; | ||
const headers = ['User ID', 'Last Updated', 'Status', 'Delete']; | ||
onMounted(async () => { | ||
isBackupsEnabled.value = await backupState.isBackupEnabled(); | ||
currentUserId.value = await backupState.getUserId(); | ||
backups.value = await backupState.listBackups(); | ||
loading.value = false; | ||
}); | ||
const toggleBackups = async (checked: boolean) => { | ||
isBackupsEnabled.value = checked; | ||
loading.value = true; | ||
if (isBackupsEnabled.value) { | ||
await backupState.enableBackups(); | ||
await backupState.backup(false); | ||
backups.value = await backupState.listBackups(); | ||
} else { | ||
await backupState.disableBackups(); | ||
} | ||
loading.value = false; | ||
}; | ||
const deleteBackup = async (userId: string) => { | ||
loading.value = true; | ||
await backupState.deleteBackup(userId); | ||
backups.value = await backupState.listBackups(); | ||
loading.value = false; | ||
}; | ||
const formatDate = (dateString: string) => { | ||
const options: Intl.DateTimeFormatOptions = { | ||
year: 'numeric', | ||
month: 'short', | ||
day: '2-digit', | ||
}; | ||
return new Date(dateString).toLocaleDateString(undefined, options); | ||
}; | ||
</script> | ||
|
||
<style lang="less"> | ||
@import '@action/styles/theme.less'; | ||
.settings { | ||
&__label { | ||
padding: 0 48px; | ||
margin-bottom: 10px; | ||
p { | ||
font-style: normal; | ||
font-weight: 400; | ||
font-size: 12px; | ||
line-height: 16px; | ||
letter-spacing: 0.5px; | ||
color: @tertiaryLabel; | ||
margin: 0; | ||
.settings-container { | ||
padding: 16px; | ||
} | ||
.settings__label { | ||
padding: 0 48px; | ||
margin-bottom: 10px; | ||
p { | ||
font-style: normal; | ||
font-weight: 400; | ||
font-size: 14px; | ||
color: @tertiaryLabel; | ||
} | ||
} | ||
.settings__backup-header { | ||
font-style: normal; | ||
font-weight: bold; | ||
font-size: 16px; | ||
margin: 30px 0 15px; | ||
} | ||
.settings__backup-table { | ||
width: 100%; | ||
border-collapse: collapse; | ||
border-radius: 12px; | ||
overflow: hidden; | ||
background: @primaryBg; | ||
&__loader-one { | ||
width: 100px; | ||
} | ||
&__loader-two { | ||
width: 65px; | ||
} | ||
thead { | ||
background: @darkBg; | ||
th { | ||
padding: 10px; | ||
text-align: left; | ||
font-weight: bold; | ||
text-align: center; | ||
height: 30px; | ||
&:first-child { | ||
width: 150px; | ||
} | ||
} | ||
} | ||
&__wrap { | ||
.base-select__container { | ||
margin-bottom: 12px; | ||
tbody { | ||
tr { | ||
&:nth-child(even) { | ||
background: @primary007; | ||
} | ||
} | ||
td { | ||
padding: 10px; | ||
border-bottom: 1px solid @default; | ||
text-align: center; | ||
&:nth-child(1) { | ||
text-align: left; | ||
} | ||
} | ||
} | ||
&__status-badge { | ||
padding: 4px 8px; | ||
border-radius: 12px; | ||
font-size: 12px; | ||
font-weight: bold; | ||
} | ||
&__status-active { | ||
background: #d4f5d4; | ||
color: #2a7a2a; | ||
} | ||
&__status-inactive { | ||
background: #fddede; | ||
color: #b02a2a; | ||
} | ||
&__action-button { | ||
cursor: pointer; | ||
} | ||
} | ||
</style> |