Browse Source

fix: update style

pull/6423/head
DarkPhoenix2704 1 year ago
parent
commit
ead92b2a49
  1. 4
      packages/nc-gui/assets/nc-icons/link.svg
  2. 6
      packages/nc-gui/assets/style.scss
  3. 1
      packages/nc-gui/components.d.ts
  4. 6
      packages/nc-gui/components/virtual-cell/components/Header.vue
  5. 64
      packages/nc-gui/components/virtual-cell/components/ListChildItems.vue
  6. 41
      packages/nc-gui/components/virtual-cell/components/ListItem.vue
  7. 63
      packages/nc-gui/components/virtual-cell/components/ListItems.vue
  8. 28
      packages/nc-gui/composables/useLTARStore.ts

4
packages/nc-gui/assets/nc-icons/link.svg

@ -0,0 +1,4 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.6665 9.16668C6.95281 9.54943 7.31808 9.86613 7.73754 10.0953C8.157 10.3245 8.62084 10.4608 9.0976 10.4949C9.57437 10.529 10.0529 10.4603 10.5007 10.2932C10.9486 10.1261 11.3552 9.86473 11.6932 9.52668L13.6932 7.52668C14.3004 6.89801 14.6363 6.056 14.6288 5.18201C14.6212 4.30802 14.2706 3.47198 13.6526 2.85395C13.0345 2.23592 12.1985 1.88536 11.3245 1.87777C10.4505 1.87017 9.60851 2.20615 8.97984 2.81335L7.83317 3.95335" stroke="#3366FF" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.33347 7.83332C9.04716 7.45057 8.68189 7.13387 8.26243 6.90469C7.84297 6.67552 7.37913 6.53924 6.90237 6.5051C6.4256 6.47095 5.94707 6.53974 5.49924 6.7068C5.0514 6.87386 4.64472 7.13527 4.3068 7.47332L2.3068 9.47332C1.69961 10.102 1.36363 10.944 1.37122 11.818C1.37881 12.692 1.72938 13.528 2.3474 14.146C2.96543 14.7641 3.80147 15.1146 4.67546 15.1222C5.54945 15.1298 6.39146 14.7938 7.02013 14.1867L8.16013 13.0467" stroke="#3366FF" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

6
packages/nc-gui/assets/style.scss

@ -33,7 +33,7 @@
} }
.anticon-check-circle { .anticon-check-circle {
@apply !relative top-[-1px] left-0; @apply !relative top-[-1px] left-0;
} }
html, html,
@ -580,10 +580,6 @@ input[type='number'] {
@apply !block; @apply !block;
} }
.ant-card-body {
@apply !p-2;
}
.ant-pagination .ant-pagination-item-link-icon { .ant-pagination .ant-pagination-item-link-icon {
@apply !block !py-1.5; @apply !block !py-1.5;
} }

1
packages/nc-gui/components.d.ts vendored

@ -158,6 +158,7 @@ declare module '@vue/runtime-core' {
MdiWhatsapp: typeof import('~icons/mdi/whatsapp')['default'] MdiWhatsapp: typeof import('~icons/mdi/whatsapp')['default']
MiCircleWarning: typeof import('~icons/mi/circle-warning')['default'] MiCircleWarning: typeof import('~icons/mi/circle-warning')['default']
NcIconsInbox: typeof import('~icons/nc-icons/inbox')['default'] NcIconsInbox: typeof import('~icons/nc-icons/inbox')['default']
PhLink: typeof import('~icons/ph/link')['default']
PhMagnifyingGlassBold: typeof import('~icons/ph/magnifying-glass-bold')['default'] PhMagnifyingGlassBold: typeof import('~icons/ph/magnifying-glass-bold')['default']
PhTriangleFill: typeof import('~icons/ph/triangle-fill')['default'] PhTriangleFill: typeof import('~icons/ph/triangle-fill')['default']
RiExternalLinkLine: typeof import('~icons/ri/external-link-line')['default'] RiExternalLinkLine: typeof import('~icons/ri/external-link-line')['default']

6
packages/nc-gui/components/virtual-cell/components/Header.vue

@ -49,9 +49,9 @@ const relationMeta = computed(() => {
<template> <template>
<div class="flex justify-between relative pb-2 items-center"> <div class="flex justify-between relative pb-2 items-center">
<h2 class="text-md font-semibold"> <span class="text-md font-semibold flex mt-2 justify-center">
{{ showHeader ? 'Linked Records' : '' }} {{ showHeader ? 'Linked Records' : '' }}
</h2> </span>
<div class="grid grid-cols-[1fr,auto,1fr] justify-center items-center gap-2 absolute inset-0 m-auto"> <div class="grid grid-cols-[1fr,auto,1fr] justify-center items-center gap-2 absolute inset-0 m-auto">
<div class="flex justify-end"> <div class="flex justify-end">
<div class="flex flex-shrink-0 rounded-md gap-1 text-brand-500 items-center bg-gray-100 px-2 py-1"> <div class="flex flex-shrink-0 rounded-md gap-1 text-brand-500 items-center bg-gray-100 px-2 py-1">
@ -108,7 +108,7 @@ const relationMeta = computed(() => {
</div> </div>
</div> </div>
</template> </template>
<InfoIcon class="w-4 h-4" /> <InfoIcon class="w-4 h-4 mt-2" />
</NcTooltip> </NcTooltip>
</div> </div>
</template> </template>

64
packages/nc-gui/components/virtual-cell/components/ListChildItems.vue

@ -12,6 +12,7 @@ import {
computed, computed,
inject, inject,
isPrimary, isPrimary,
onKeyStroke,
ref, ref,
useLTARStoreOrThrow, useLTARStoreOrThrow,
useSmartsheetRowStoreOrThrow, useSmartsheetRowStoreOrThrow,
@ -41,6 +42,7 @@ const {
unlink, unlink,
isChildrenListLoading, isChildrenListLoading,
isChildrenListLinked, isChildrenListLinked,
isChildrenLoading,
relatedTableMeta, relatedTableMeta,
row, row,
link, link,
@ -112,7 +114,13 @@ watch(
) )
watch(expandedFormDlg, () => { watch(expandedFormDlg, () => {
loadChildrenList() if (!expandedFormDlg.value) {
loadChildrenList()
}
})
onKeyStroke('Escape', () => {
vModel.value = false
}) })
</script> </script>
@ -131,6 +139,7 @@ watch(expandedFormDlg, () => {
:relation="relation" :relation="relation"
:linked-records="childrenListCount" :linked-records="childrenListCount"
:table-title="meta?.title" :table-title="meta?.title"
:show-header="true"
:related-table-title="relatedTableMeta?.title" :related-table-title="relatedTableMeta?.title"
:display-value="row.row[displayValueProp]" :display-value="row.row[displayValueProp]"
/> />
@ -167,28 +176,33 @@ watch(expandedFormDlg, () => {
}" }"
class="overflow-scroll nc-scrollbar-md cursor-pointer pr-1" class="overflow-scroll nc-scrollbar-md cursor-pointer pr-1"
> >
<LazyVirtualCellComponentsListItem <template v-if="isChildrenLoading">
v-for="(refRow, id) in childrenList?.list ?? state?.[colTitle] ?? []" <a-skeleton v-for="(x, i) in Array.from({ length: 10 })" :key="i" active> </a-skeleton>
:key="id" </template>
:row="refRow" <template v-else>
:fields="fields" <LazyVirtualCellComponentsListItem
data-testid="nc-child-list-item" v-for="(refRow, id) in childrenList?.list ?? state?.[colTitle] ?? []"
:attachment="attachmentCol" :key="id"
:related-table-display-value-prop="relatedTableDisplayValueProp" :row="refRow"
:is-linked="childrenList?.list ? isChildrenListLinked[Number.parseInt(id)] : true" :fields="fields"
:is-loading="isChildrenListLoading[Number.parseInt(id)]" data-testid="nc-child-list-item"
@expand="onClick(refRow)" :attachment="attachmentCol"
@click=" :related-table-display-value-prop="relatedTableDisplayValueProp"
() => { :is-linked="childrenList?.list ? isChildrenListLinked[Number.parseInt(id)] : true"
if (isPublic && !isForm) return :is-loading="isChildrenListLoading[Number.parseInt(id)]"
isNew @expand="onClick(refRow)"
? unlinkRow(refRow, Number.parseInt(id)) @click="
: isChildrenListLinked[Number.parseInt(id)] () => {
? unlinkRow(refRow, Number.parseInt(id)) if (isPublic && !isForm) return
: linkRow(refRow, Number.parseInt(id)) isNew
} ? unlinkRow(refRow, Number.parseInt(id))
" : isChildrenListLinked[Number.parseInt(id)]
/> ? unlinkRow(refRow, Number.parseInt(id))
: linkRow(refRow, Number.parseInt(id))
}
"
/>
</template>
</div> </div>
</div> </div>
</template> </template>
@ -220,10 +234,10 @@ watch(expandedFormDlg, () => {
<div class="my-2 bg-gray-50 border-gray-50 border-b-2"></div> <div class="my-2 bg-gray-50 border-gray-50 border-b-2"></div>
<div class="flex flex-row justify-between bg-white relative pt-1"> <div class="flex flex-row justify-between bg-white relative pt-1">
<div v-if="!isForm" class="flex items-center justify-center px-2 rounded-md text-brand-500 bg-brand-50"> <div v-if="!isForm" class="flex items-center justify-center px-2 rounded-md text-gray-500 bg-brand-50">
{{ childrenListCount || 0 }} records {{ childrenListCount !== 0 ? 'are' : '' }} linked {{ childrenListCount || 0 }} records {{ childrenListCount !== 0 ? 'are' : '' }} linked
</div> </div>
<div v-else class="flex items-center justify-center px-2 rounded-md text-brand-500 bg-brand-50"> <div v-else class="flex items-center justify-center px-2 rounded-md text-gray-500 bg-brand-50">
{{ state?.[colTitle]?.length || 0 }} records {{ state?.[colTitle]?.length !== 0 ? 'are' : '' }} linked {{ state?.[colTitle]?.length || 0 }} records {{ state?.[colTitle]?.length !== 0 ? 'are' : '' }} linked
</div> </div>
<div class="flex absolute items-center py-2 justify-center w-full"> <div class="flex absolute items-center py-2 justify-center w-full">

41
packages/nc-gui/components/virtual-cell/components/ListItem.vue

@ -2,6 +2,7 @@
import { isVirtualCol } from 'nocodb-sdk' import { isVirtualCol } from 'nocodb-sdk'
import { IsFormInj, isImage, useAttachment } from '#imports' import { IsFormInj, isImage, useAttachment } from '#imports'
import MaximizeIcon from '~icons/nc-icons/maximize' import MaximizeIcon from '~icons/nc-icons/maximize'
import LinkIcon from '~icons/nc-icons/link'
const { row, fields, relatedTableDisplayValueProp, isLoading, isLinked, attachment } = defineProps<{ const { row, fields, relatedTableDisplayValueProp, isLoading, isLinked, attachment } = defineProps<{
row: any row: any
@ -46,42 +47,40 @@ const attachments: Attachment[] = computed(() => {
<a-card <a-card
class="!border-1 group transition-all !rounded-xl relative !mb-2 !border-gray-200 hover:bg-gray-50" class="!border-1 group transition-all !rounded-xl relative !mb-2 !border-gray-200 hover:bg-gray-50"
:class="{ :class="{
'!bg-white !border-blue-500': isLoading, '!bg-white': isLoading,
'!border-brand-500 !bg-brand-50 !border-2 !hover:bg-brand-50 !hover:border-brand-500': isLinked, ' !border-1': isLinked,
'!hover:border-gray-400': !isLinked, '!hover:border-gray-400': !isLinked,
}" }"
:body-style="{ padding: 0 }" :body-style="{ padding: 0 }"
:hoverable="false" :hoverable="false"
> >
<div class="flex flex-row items-center gap-2 w-full"> <div class="flex flex-row items-center justify-start w-full">
<a-carousel <a-carousel v-if="attachment && attachments && attachments.length" autoplay class="!w-24 !h-24">
v-if="attachment && attachments && attachments.length"
autoplay
class="!w-24 border-1 bg-white border-gray-200 !rounded-md !h-24"
>
<template #customPaging> </template> <template #customPaging> </template>
<template v-for="(attachmen, index) in attachments"> <template v-for="(attachmen, index) in attachments">
<LazyCellAttachmentImage <LazyCellAttachmentImage
v-if="isImage(attachmen.title, attachmen.mimetype ?? attachmen.type)" v-if="isImage(attachmen.title, attachmen.mimetype ?? attachmen.type)"
:key="`carousel-${attachmen.title}-${index}`" :key="`carousel-${attachmen.title}-${index}`"
class="!h-24 !w-24 object-cover !rounded-md" class="!h-24 !w-24 object-cover !rounded-l-xl"
:srcs="getPossibleAttachmentSrc(attachmen)" :srcs="getPossibleAttachmentSrc(attachmen)"
/> />
</template> </template>
</a-carousel> </a-carousel>
<div v-else-if="attachment" class="h-24 w-24 w-full !flex flex-row items-center justify-center"> <div v-else-if="attachment" class="h-24 w-24 w-full !flex flex-row items-center !rounded-l-xl justify-center">
<img class="object-contain h-24 w-24" src="~assets/icons/FileIconImageBox.png" /> <img class="object-contain h-24 w-24" src="~assets/icons/FileIconImageBox.png" />
</div> </div>
<div class="flex flex-col gap-1 flex-grow justify-center"> <div class="flex flex-col m-[.75rem] gap-1 flex-grow justify-center">
<div class="flex justify-between"> <div class="flex justify-between">
<span class="font-bold text-gray-800 ml-1 nc-display-value"> {{ row[relatedTableDisplayValueProp] }} </span> <span class="font-semibold text-gray-800 nc-display-value"> {{ row[relatedTableDisplayValueProp] }} </span>
<MdiCheck <div v-if="isLinked" class="text-brand-500 text-0.875">
v-if="isLinked" <LinkIcon
:class="{ :class="{
'!group-hover:mr-8': fields.length === 0, '!group-hover:mr-8': fields.length === 0,
}" }"
class="w-6 h-6 !text-brand-500" class="w-4 h-4"
/> />
Linked
</div>
<MdiLoading <MdiLoading
v-else-if="isLoading" v-else-if="isLoading"
:class="{ :class="{
@ -91,7 +90,7 @@ const attachments: Attachment[] = computed(() => {
/> />
</div> </div>
<div v-if="fields.length > 0 && !isPublic && !isForm" class="flex flex-row gap-4 w-10/12"> <div v-if="fields.length > 0 && !isPublic && !isForm" class="flex ml-[-0.25rem] flex-row gap-4 w-10/12">
<div v-for="field in fields" :key="field.id" :class="attachment ? 'w-1/3' : 'w-1/4'"> <div v-for="field in fields" :key="field.id" :class="attachment ? 'w-1/3' : 'w-1/4'">
<div class="flex flex-col gap-[-1] max-w-72"> <div class="flex flex-col gap-[-1] max-w-72">
<LazySmartsheetHeaderVirtualCell <LazySmartsheetHeaderVirtualCell
@ -121,7 +120,7 @@ const attachments: Attachment[] = computed(() => {
v-if="!isForm && !isPublic" v-if="!isForm && !isPublic"
type="text" type="text"
size="lg" size="lg"
class="!px-2 nc-expand-item !group-hover:block !hidden !absolute right-1 bottom-1" class="!px-2 nc-expand-item !group-hover:block !hidden !border-1 !shadow-sm !border-gray-200 !bg-white !absolute right-3 bottom-3"
@click.stop="$emit('expand', row)" @click.stop="$emit('expand', row)"
> >
<MaximizeIcon class="w-4 h-4" /> <MaximizeIcon class="w-4 h-4" />

63
packages/nc-gui/components/virtual-cell/components/ListItems.vue

@ -9,6 +9,7 @@ import {
SaveRowInj, SaveRowInj,
computed, computed,
inject, inject,
onKeyStroke,
ref, ref,
useLTARStoreOrThrow, useLTARStoreOrThrow,
useSmartsheetRowStoreOrThrow, useSmartsheetRowStoreOrThrow,
@ -30,6 +31,7 @@ const {
isChildrenExcludedListLinked, isChildrenExcludedListLinked,
isChildrenExcludedListLoading, isChildrenExcludedListLoading,
displayValueProp, displayValueProp,
isChildrenExcludedLoading,
childrenListCount, childrenListCount,
loadChildrenExcludedList, loadChildrenExcludedList,
loadChildrenList, loadChildrenList,
@ -138,7 +140,13 @@ const relation = computed(() => {
}) })
watch(expandedFormDlg, () => { watch(expandedFormDlg, () => {
loadChildrenExcludedList(rowState.value) if (!expandedFormDlg.value) {
loadChildrenExcludedList(rowState.value)
}
})
onKeyStroke('Escape', () => {
vModel.value = false
}) })
</script> </script>
@ -203,29 +211,34 @@ watch(expandedFormDlg, () => {
<template v-if="childrenExcludedList?.pageInfo?.totalRows"> <template v-if="childrenExcludedList?.pageInfo?.totalRows">
<div class="pb-2 pt-1"> <div class="pb-2 pt-1">
<div class="h-[420px] overflow-scroll nc-scrollbar-md pr-1 cursor-pointer"> <div class="h-[420px] overflow-scroll nc-scrollbar-md pr-1 cursor-pointer">
<LazyVirtualCellComponentsListItem <template v-if="isChildrenExcludedLoading">
v-for="(refRow, id) in childrenExcludedList?.list ?? []" <a-skeleton v-for="(x, i) in Array.from({ length: 10 })" :key="i" active> </a-skeleton>
:key="id" </template>
data-testid="nc-excluded-list-item" <template v-else>
:row="refRow" <LazyVirtualCellComponentsListItem
:fields="fields" v-for="(refRow, id) in childrenExcludedList?.list ?? []"
:attachment="attachmentCol" :key="id"
:related-table-display-value-prop="relatedTableDisplayValueProp" data-testid="nc-excluded-list-item"
:is-loading="isChildrenExcludedListLoading[Number.parseInt(id)]" :row="refRow"
:is-linked="isChildrenExcludedListLinked[Number.parseInt(id)]" :fields="fields"
@expand=" :attachment="attachmentCol"
() => { :related-table-display-value-prop="relatedTableDisplayValueProp"
expandedFormRow = refRow :is-loading="isChildrenExcludedListLoading[Number.parseInt(id)]"
expandedFormDlg = true :is-linked="isChildrenExcludedListLinked[Number.parseInt(id)]"
} @expand="
" () => {
@click=" expandedFormRow = refRow
() => { expandedFormDlg = true
if (isChildrenExcludedListLinked[Number.parseInt(id)]) unlinkRow(refRow, Number.parseInt(id)) }
else linkRow(refRow, Number.parseInt(id)) "
} @click="
" () => {
/> if (isChildrenExcludedListLinked[Number.parseInt(id)]) unlinkRow(refRow, Number.parseInt(id))
else linkRow(refRow, Number.parseInt(id))
}
"
/>
</template>
</div> </div>
</div> </div>
</template> </template>
@ -242,7 +255,7 @@ watch(expandedFormDlg, () => {
<div class="my-2 bg-gray-50 border-gray-50 border-b-2"></div> <div class="my-2 bg-gray-50 border-gray-50 border-b-2"></div>
<div class="flex flex-row justify-between bg-white relative pt-1"> <div class="flex flex-row justify-between bg-white relative pt-1">
<div v-if="!isForm" class="flex items-center justify-center px-2 rounded-md text-brand-500 bg-brand-50"> <div v-if="!isForm" class="flex items-center justify-center px-2 rounded-md text-gray-500 bg-brand-50">
{{ relation === 'bt' ? (row.row[relatedTableMeta?.title] ? '1' : 0) : childrenListCount ?? 'No' }} records {{ relation === 'bt' ? (row.row[relatedTableMeta?.title] ? '1' : 0) : childrenListCount ?? 'No' }} records
{{ childrenListCount !== 0 ? 'are' : '' }} linked {{ childrenListCount !== 0 ? 'are' : '' }} linked
</div> </div>

28
packages/nc-gui/composables/useLTARStore.ts

@ -64,12 +64,16 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
size: 10, size: 10,
}) })
const isChildrenLoading = ref(false)
const isChildrenListLoading = ref<Array<boolean>>([]) const isChildrenListLoading = ref<Array<boolean>>([])
const isChildrenListLinked = ref<Array<boolean>>([]) const isChildrenListLinked = ref<Array<boolean>>([])
const isChildrenExcludedListLoading = ref<Array<boolean>>([]) const isChildrenExcludedListLoading = ref<Array<boolean>>([])
const isChildrenExcludedLoading = ref(false)
const isChildrenExcludedListLinked = ref<Array<boolean>>([]) const isChildrenExcludedListLinked = ref<Array<boolean>>([])
const newRowState = reactive({ const newRowState = reactive({
@ -127,6 +131,7 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
const loadChildrenExcludedList = async (activeState?: any) => { const loadChildrenExcludedList = async (activeState?: any) => {
if (activeState) newRowState.state = activeState if (activeState) newRowState.state = activeState
try { try {
isChildrenExcludedLoading.value = true
if (isPublic.value) { if (isPublic.value) {
const router = useRouter() const router = useRouter()
@ -212,11 +217,16 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
} }
} catch (e: any) { } catch (e: any) {
message.error(`${t('msg.error.failedToLoadList')}: ${await extractSdkResponseErrorMsg(e)}`) message.error(`${t('msg.error.failedToLoadList')}: ${await extractSdkResponseErrorMsg(e)}`)
} finally {
setTimeout(() => {
isChildrenExcludedLoading.value = false
}, 600)
} }
} }
const loadChildrenList = async () => { const loadChildrenList = async () => {
try { try {
isChildrenLoading.value = true
if (colOptions.value.type === 'bt') return if (colOptions.value.type === 'bt') return
if (!rowId.value || !column.value) return if (!rowId.value || !column.value) return
if (isPublic.value) { if (isPublic.value) {
@ -262,6 +272,10 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
} }
} catch (e: any) { } catch (e: any) {
message.error(`${t('msg.error.failedToLoadChildrenList')}: ${await extractSdkResponseErrorMsg(e)}`) message.error(`${t('msg.error.failedToLoadChildrenList')}: ${await extractSdkResponseErrorMsg(e)}`)
} finally {
setTimeout(() => {
isChildrenLoading.value = false
}, 600)
} }
} }
@ -357,8 +371,10 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
} catch (e: any) { } catch (e: any) {
message.error(`${t('msg.error.unlinkFailed')}: ${await extractSdkResponseErrorMsg(e)}`) message.error(`${t('msg.error.unlinkFailed')}: ${await extractSdkResponseErrorMsg(e)}`)
} finally { } finally {
isChildrenExcludedListLoading.value[index] = false setTimeout(() => {
isChildrenListLoading.value[index] = false isChildrenExcludedListLoading.value[index] = false
isChildrenListLoading.value[index] = false
}, 600)
} }
reloadData?.(false) reloadData?.(false)
@ -422,8 +438,10 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
} catch (e: any) { } catch (e: any) {
message.error(`Linking failed: ${await extractSdkResponseErrorMsg(e)}`) message.error(`Linking failed: ${await extractSdkResponseErrorMsg(e)}`)
} finally { } finally {
isChildrenExcludedListLoading.value[index] = false setTimeout(() => {
isChildrenListLoading.value[index] = false isChildrenExcludedListLoading.value[index] = false
isChildrenListLoading.value[index] = false
}, 600)
} }
reloadData?.(false) reloadData?.(false)
@ -466,6 +484,8 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
isChildrenListLoading, isChildrenListLoading,
isChildrenExcludedListLoading, isChildrenExcludedListLoading,
row, row,
isChildrenLoading,
isChildrenExcludedLoading,
deleteRelatedRow, deleteRelatedRow,
getRelatedTableRowId, getRelatedTableRowId,
} }

Loading…
Cancel
Save