Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nc fix/UI ux fixes #7286

Merged
merged 4 commits into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const validators = computed(() => {
{
validator: (rule: any, value: string, callback: (errMsg?: string) => void) => {
if (!value || value.length === 0) {
callback(t('msg.error.signUpRules.emailReqd'))
callback(t('msg.error.signUpRules.emailRequired'))
return
}
const invalidEmails = (value || '').split(/\s*,\s*/).filter((e: string) => !validateEmail(e))
Expand Down
19 changes: 14 additions & 5 deletions packages/nc-gui/components/project/AccessSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
WorkspaceRolesToProjectRoles,
extractRolesObj,
timeAgo,
parseStringDateTime,
} from 'nocodb-sdk'
import type { WorkspaceUserRoles } from 'nocodb-sdk'
import { isEeUI, storeToRefs } from '#imports'
Expand Down Expand Up @@ -145,8 +146,8 @@ const filteredCollaborators = computed(() =>
<div class="flex flex-col rounded-lg overflow-hidden border-1 max-w-350 max-h-[calc(100%-8rem)]">
<div class="flex flex-row bg-gray-50 min-h-12 items-center border-b-1">
<div class="text-gray-700 users-email-grid">{{ $t('objects.users') }}</div>
<div class="text-gray-700 date-joined-grid">{{ $t('title.dateJoined') }}</div>
<div class="text-gray-700 user-access-grid">{{ $t('general.access') }}</div>
<div class="text-gray-700 date-joined-grid">{{ $t('title.dateJoined') }}</div>
</div>

<div class="flex flex-col nc-scrollbar-md">
Expand All @@ -161,7 +162,6 @@ const filteredCollaborators = computed(() =>
{{ collab.email }}
</span>
</div>
<div class="date-joined-grid">{{ timeAgo(collab.created_at) }}</div>
<div class="user-access-grid">
<template v-if="accessibleRoles.includes(collab.roles)">
<RolesSelector
Expand All @@ -180,6 +180,16 @@ const filteredCollaborators = computed(() =>
<RolesBadge :role="collab.roles" />
</template>
</div>
<div class="date-joined-grid">
<NcTooltip class="max-w-full">
<template #title>
{{ parseStringDateTime(collab.created_at) }}
</template>
<span>
{{ timeAgo(collab.created_at) }}
</span>
</NcTooltip>
</div>
</div>
</div>
</div>
Expand All @@ -206,12 +216,11 @@ const filteredCollaborators = computed(() =>
}

.date-joined-grid {
@apply flex items-start;
width: calc(50% - 10rem);
@apply w-1/4 flex items-start;
}

.user-access-grid {
@apply w-40;
@apply w-1/4 flex justify-start;
}

.user-row {
Expand Down
17 changes: 13 additions & 4 deletions packages/nc-gui/components/workspace/CollaboratorsList.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import { OrderedWorkspaceRoles, WorkspaceUserRoles, timeAgo } from 'nocodb-sdk'
import { OrderedWorkspaceRoles, WorkspaceUserRoles, parseStringDateTime, timeAgo } from 'nocodb-sdk'
import { storeToRefs, useWorkspace } from '#imports'

const { workspaceRoles, loadRoles } = useRoles()
Expand Down Expand Up @@ -59,9 +59,9 @@ onMounted(async () => {
<div v-else class="nc-collaborators-list mt-6 h-full">
<div class="flex flex-col rounded-lg overflow-hidden border-1 max-w-350 max-h-[calc(100%-8rem)]">
<div class="flex flex-row bg-gray-50 min-h-12 items-center">
<div class="text-gray-700 users-email-grid w-3/8 ml-10">{{ $t('objects.users') }}</div>
<div class="text-gray-700 date-joined-grid w-2/8 mr-3 pl-1">{{ $t('title.dateJoined') }}</div>
<div class="text-gray-700 users-email-grid w-3/8 ml-10 mr-3">{{ $t('objects.users') }}</div>
<div class="text-gray-700 user-access-grid w-2/8 mr-3">{{ $t('general.access') }}</div>
<div class="text-gray-700 date-joined-grid w-2/8 mr-3">{{ $t('title.dateJoined') }}</div>
<div class="text-gray-700 user-access-grid w-1/8">Actions</div>
</div>

Expand All @@ -77,7 +77,6 @@ onMounted(async () => {
{{ collab.email }}
</span>
</div>
<div class="date-joined-grid w-2/8">{{ timeAgo(collab.created_at) }}</div>
<div class="user-access-grid w-2/8">
<template v-if="accessibleRoles.includes(collab.roles)">
<div class="w-[30px]">
Expand All @@ -94,6 +93,16 @@ onMounted(async () => {
<RolesBadge :role="collab.roles" class="cursor-default" />
</template>
</div>
<div class="date-joined-grid w-2/8 flex justify-start">
<NcTooltip class="max-w-full">
<template #title>
{{ parseStringDateTime(collab.created_at) }}
</template>
<span>
{{ timeAgo(collab.created_at) }}
</span>
</NcTooltip>
</div>
<div class="w-1/8 pl-6">
<NcDropdown v-if="collab.roles !== WorkspaceUserRoles.OWNER" :trigger="['click']">
<MdiDotsVertical
Expand Down
5 changes: 3 additions & 2 deletions packages/nc-gui/pages/forgot-password.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ const form = reactive({
const formRules = {
email: [
// E-mail is required
{ required: true, message: t('msg.error.signUpRules.emailReqd') },
{ required: true, message: t('msg.error.signUpRules.emailRequired') },
// E-mail must be valid format
{
validator: (_: unknown, v: string) => {
return new Promise((resolve, reject) => {
if (validateEmail(v)) return resolve()
if (!v?.length || validateEmail(v)) return resolve()

reject(new Error(t('msg.error.signUpRules.emailInvalid')))
})
},
Expand Down
4 changes: 2 additions & 2 deletions packages/nc-gui/pages/signin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ const form = reactive({
const formRules: Record<string, RuleObject[]> = {
email: [
// E-mail is required
{ required: true, message: t('msg.error.signUpRules.emailReqd') },
{ required: true, message: t('msg.error.signUpRules.emailRequired') },
// E-mail must be valid format
{
validator: (_: unknown, v: string) => {
return new Promise((resolve, reject) => {
if (validateEmail(v)) return resolve()
if (!v?.length || validateEmail(v)) return resolve()

reject(new Error(t('msg.error.signUpRules.emailInvalid')))
})
Expand Down
3 changes: 2 additions & 1 deletion packages/nc-gui/pages/signup/[[token]].vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ const form = reactive({
const formRules = {
email: [
// E-mail is required
{ required: true, message: t('msg.error.signUpRules.emailReqd') },
{ required: true, message: t('msg.error.signUpRules.emailRequired') },
// E-mail must be valid format
{
validator: (_: unknown, v: string) => {
return new Promise((resolve, reject) => {
if (!v?.length || validateEmail(v)) return resolve()

reject(new Error(t('msg.error.signUpRules.emailInvalid')))
})
},
Expand Down
15 changes: 15 additions & 0 deletions packages/nocodb-sdk/src/lib/dateTimeHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,21 @@ export function parseStringDate(v: string, dateFormat: string) {
return v;
}

export function parseStringDateTime(
v: string,
dateTimeFormat: string = `${dateFormats[0]} ${timeFormats[0]}`
) {
const dayjsObj = dayjs(v).local();

if (dayjsObj.isValid()) {
v = dayjsObj.format(dateTimeFormat);
} else {
v = dayjs(v, dateTimeFormat).local().format(dateTimeFormat);
}

return v;
}

export function convertToTargetFormat(
v: string,
oldDataFormat,
Expand Down
12 changes: 9 additions & 3 deletions tests/playwright/pages/Dashboard/common/Cell/SelectOptionCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ export class SelectOptionCellPageObject extends BasePage {

await selectCell.click();

if (index === -1)
await this.rootPage.getByTestId(`select-option-${columnHeader}-undefined`).getByText(option).click();
else await this.rootPage.getByTestId(`select-option-${columnHeader}-${index}`).getByText(option).click();
if (index === -1) {
const selectOption = this.rootPage.getByTestId(`select-option-${columnHeader}-undefined`).getByText(option);
await selectOption.waitFor({ state: 'visible' });
await selectOption.click();
} else {
const selectOption = this.rootPage.getByTestId(`select-option-${columnHeader}-${index}`).getByText(option);
await selectOption.waitFor({ state: 'visible' });
await selectOption.click();
}

if (multiSelect) await this.get({ index, columnHeader }).click();

Expand Down
12 changes: 9 additions & 3 deletions tests/playwright/pages/Dashboard/common/Cell/UserOptionCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,15 @@ export class UserOptionCellPageObject extends BasePage {

await selectCell.click();

if (index === -1)
await this.rootPage.getByTestId(`select-option-${columnHeader}-undefined`).getByText(option).click();
else await this.rootPage.getByTestId(`select-option-${columnHeader}-${index}`).getByText(option).click();
if (index === -1) {
const selectOption = this.rootPage.getByTestId(`select-option-${columnHeader}-undefined`).getByText(option);
await selectOption.waitFor({ state: 'visible' });
await selectOption.click();
} else {
const selectOption = this.rootPage.getByTestId(`select-option-${columnHeader}-${index}`).getByText(option);
await selectOption.waitFor({ state: 'visible' });
await selectOption.click();
}

if (multiSelect) await this.get({ index, columnHeader }).click();

Expand Down