Skip to content

Commit

Permalink
Implement advanced cloud settings
Browse files Browse the repository at this point in the history
  • Loading branch information
NoelDeMartin committed Jun 14, 2024
1 parent 3472a37 commit e6a27c8
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 56 deletions.
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"dependencies": {
"@aerogel/core": "0.0.0-next.d34923f3b144e8f6720e6a9cdadb2cd4fb4ab289",
"@aerogel/plugin-i18n": "0.0.0-next.464f8d4bc58710df35b52ea396ccd8c40b73c664",
"@aerogel/plugin-offline-first": "0.0.0-next.9f9564ab9f8da05f60d7868db361edbc5601ee39",
"@aerogel/plugin-offline-first": "0.0.0-next.48d1b831865f6aed1e507163c2737622ea542044",
"@aerogel/plugin-routing": "0.0.0-next.d34923f3b144e8f6720e6a9cdadb2cd4fb4ab289",
"@aerogel/plugin-solid": "0.0.1-next.73d70336b0cf4417d777c5ba96037344f5726eef",
"@aerogel/plugin-soukai": "0.0.0-next.71f28064caa2ea968f0e99396b672de218176260",
Expand Down
9 changes: 9 additions & 0 deletions src/assets/css/helpers.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@
right: var(--clickable-inset-by);
bottom: var(--clickable-inset-by);
}

input[type='number'].appearance-textfield {
appearance: textfield;
}

input[type='number'].appearance-textfield::-webkit-outer-spin-button,
input[type='number'].appearance-textfield::-webkit-inner-spin-button {
appearance: none;
}
16 changes: 12 additions & 4 deletions src/components/forms/EditableContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
<span v-else :class="renderedFillerClass">
{{ draft }}
</span>
<span v-if="type === 'number'" class="inline-block transition-[width]" :class="editing ? 'w-5' : 'w-0'" />
<form class="w-full" @submit.prevent="$input?.blur()">
<input
ref="$input"
v-model="draft"
type="text"
tabindex="-1"
:class="[renderedInputClass, { 'opacity-0': !editing }]"
:tabindex="tabindex ?? undefined"
:aria-label="ariaLabel ?? undefined"
:type="type"
:class="[
renderedInputClass,
{ 'opacity-0': !editing, 'appearance-textfield': !editing && type === 'number' },
]"
@keyup="$emit('update', draft)"
@focus="startEditing()"
@blur="stopEditing()"
Expand All @@ -28,7 +33,10 @@ import { twMerge } from 'tailwind-merge';
const emit = defineEmits(['update', 'save']);
const props = defineProps({
type: stringProp('text'),
contentClass: stringProp(),
ariaLabel: stringProp(),
tabindex: stringProp(),
text: requiredStringProp(),
disabled: booleanProp(),
});
Expand All @@ -49,7 +57,7 @@ function stopEditing() {
return;
}
if (draft.value.trim().length === 0) {
if (props.type !== 'number' && draft.value.trim().length === 0) {
draft.value = editing.value;
emit('update', draft.value);
Expand Down
7 changes: 7 additions & 0 deletions src/lang/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ cloud:
online: Online
syncing: Syncing
dirty: There are local changes
advanced:
title: Advanced options
reconnect: Reconnect on startup
startupSync: Synchronize on startup
polling: Synchronize every {minutes} minutes
pollingA11y: Synchronize on a fixed interval
pollingMinutes: Synchronization interval (in minutes)

footer:
about: about
Expand Down
2 changes: 2 additions & 0 deletions src/pages/workspace/components/tasks/TasksListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<EditableContent
class="overflow-y-auto truncate py-2.5 pr-1"
content-class="whitespace-pre"
tabindex="-1"
:aria-label="$t('task.name')"
:class="{ 'line-through': task.completed }"
:disabled="disableEditing"
:text="task.name"
Expand Down
4 changes: 2 additions & 2 deletions src/pages/workspace/components/user/UserStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
>
<AGSolidUserAvatar class="h-full w-full" />
<div
v-if="$cloud.syncing"
v-if="$cloud.syncing || $solid.loginOngoing"
class="absolute -inset-1 animate-spin rounded-full border-2 border-[currentColor_transparent] text-green-500"
/>
</button>
<div
class="pointer-events-none absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-white"
:class="[cloudStatusClass, $cloud.syncing && 'sr-only']"
:class="[cloudStatusClass, { 'sr-only': $cloud.syncing || $solid.loginOngoing }]"
>
<span v-if="$cloud.dirty && !$cloud.syncing" class="sr-only">{{ $t(`cloud.status.dirty`) }}</span>
<span v-else class="sr-only">{{ $t(`cloud.status.${$cloud.status}`) }}</span>
Expand Down
130 changes: 89 additions & 41 deletions src/pages/workspace/modals/CloudStatusModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,95 @@
</IconButton>
</div>

<div v-if="$cloud.syncing" class="mt-4 flex items-center gap-2">
<i-zondicons-refresh class="mt-0.5 h-6 w-6 animate-spin self-start text-green-500" />
<AGMarkdown lang-key="cloud.info.syncing" />
</div>

<div v-else-if="$solid.loginOngoing" class="mt-4 flex items-center gap-2">
<i-zondicons-refresh class="mt-0.5 h-6 w-6 animate-spin self-start text-green-500" />
<AGMarkdown lang-key="cloud.info.reconnecting" />
</div>

<div v-else-if="!$cloud.ready" class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-yellow-500" />
<AGMarkdown lang-key="cloud.info.setup" />
</div>

<div v-else-if="$cloud.dirty" class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-yellow-500" />
<AGMarkdown lang-key="cloud.info.changes" :lang-params="$cloud.localChanges" />
</div>

<div v-else-if="$cloud.online" class="mt-4 flex items-center gap-2">
<i-zondicons-checkmark-outline class="mt-0.5 h-6 w-6 self-start text-green-500" />
<AGMarkdown lang-key="cloud.info.changes" :lang-params="0" />
</div>

<div v-else-if="$solid.error" class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-red-500" />
<div>
<AGMarkdown :text="errorDescription" />
<AGLink
v-if="showErrorDetails"
class="text-sm underline opacity-50 hover:opacity-75"
@click="$errors.inspect($solid.error)"
>
{{ $t('ui.viewDetails') }}
</AGLink>
<div class="px-2">
<div v-if="$cloud.syncing" class="mt-4 flex items-center gap-2">
<i-zondicons-refresh class="mt-0.5 h-6 w-6 animate-spin self-start text-green-500" />
<AGMarkdown lang-key="cloud.info.syncing" />
</div>
</div>

<div v-else class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-yellow-500" />
<AGMarkdown lang-key="cloud.info.disconnected" />
<div v-else-if="$solid.loginOngoing" class="mt-4 flex items-center gap-2">
<i-zondicons-refresh class="mt-0.5 h-6 w-6 animate-spin self-start text-green-500" />
<AGMarkdown lang-key="cloud.info.reconnecting" />
</div>
<div v-else-if="$solid.error" class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-red-500" />
<div>
<AGMarkdown :text="errorDescription" />
<AGLink
v-if="showErrorDetails"
class="text-sm underline opacity-50 hover:opacity-75"
@click="$errors.inspect($solid.error)"
>
{{ $t('ui.viewDetails') }}
</AGLink>
</div>
</div>
<div v-else-if="!$cloud.ready" class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-yellow-500" />
<AGMarkdown lang-key="cloud.info.setup" />
</div>
<div v-else-if="$cloud.dirty" class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-yellow-500" />
<AGMarkdown lang-key="cloud.info.changes" :lang-params="$cloud.localChanges" />
</div>
<div v-else-if="$cloud.online" class="mt-4 flex items-center gap-2">
<i-zondicons-checkmark-outline class="mt-0.5 h-6 w-6 self-start text-green-500" />
<AGMarkdown lang-key="cloud.info.changes" :lang-params="0" />
</div>
<div v-else class="mt-4 flex items-center gap-2">
<i-ion-warning class="mt-0.5 h-6 w-6 self-start text-yellow-500" />
<AGMarkdown lang-key="cloud.info.disconnected" />
</div>
<details class="group mt-2 w-fit">
<summary
class="-ml-2 flex cursor-pointer list-none items-center rounded-lg py-2 pl-1 pr-3 hover:bg-gray-100 focus-visible:outline focus-visible:outline-gray-700"
>
<i-zondicons-cheveron-right class="h-6 w-6 transition-transform group-open:rotate-90" />
<span>{{ $t('cloud.advanced.title') }}</span>
</summary>
<ul class="ml-4 flex flex-col gap-2">
<li>
<label class="flex items-center">
<input
v-model="$solid.autoReconnect"
type="checkbox"
class="cursor-pointer rounded border-2 border-[--primary] text-[--primary-500] hover:bg-[--primary-100] checked:hover:text-[--primary-400] focus:ring-[--primary-500] focus-visible:ring-[--primary-500]"
>
<span class="ml-1.5">{{ $t('cloud.advanced.reconnect') }}</span>
</label>
</li>
<li>
<label class="flex items-center">
<input
v-model="$cloud.startupSync"
type="checkbox"
class="cursor-pointer rounded border-2 border-[--primary] text-[--primary-500] hover:bg-[--primary-100] checked:hover:text-[--primary-400] focus:ring-[--primary-500] focus-visible:ring-[--primary-500]"
>
<span class="ml-1.5">{{ $t('cloud.advanced.startupSync') }}</span>
</label>
</li>
<li class="flex items-center">
<input
v-model="$cloud.pollingEnabled"
type="checkbox"
class="cursor-pointer rounded border-2 border-[--primary] text-[--primary-500] hover:bg-[--primary-100] checked:hover:text-[--primary-400] focus:ring-[--primary-500] focus-visible:ring-[--primary-500]"
:aria-label="$t('cloud.advanced.pollingA11y')"
>
<div class="flex items-center">
<span class="ml-1.5" aria-hidden="true">{{ pollingText[0] }}</span>
<EditableContent
type="number"
:text="`${$cloud.pollingMinutes}`"
:aria-label="$t('cloud.advanced.pollingMinutes')"
class="mx-1 -mb-px border-b focus-within:border-[--primary-500]"
@update="$cloud.pollingMinutes = $event"
>
{{ $cloud.pollingMinutes }}
</EditableContent>
<span v-if="pollingText.length > 1" aria-hidden="true">{{ pollingText[1] }}</span>
</div>
</li>
</ul>
</details>
</div>

<div v-if="!$cloud.syncing && !$solid.loginOngoing" class="mt-4 flex flex-row-reverse justify-start gap-2">
Expand Down Expand Up @@ -84,6 +131,7 @@ import { computed } from 'vue';
import { Solid } from '@aerogel/plugin-solid';
import { translate } from '@aerogel/core';
const pollingText = translate('cloud.advanced.polling', { minutes: '%%separator%%' }).split('%%separator%%');
const errorDescription = computed(() => {
if (!Solid.error) {
return;
Expand Down

0 comments on commit e6a27c8

Please sign in to comment.