Browse Source

Merge pull request #3414 from nocodb/fix/3412-hm-mm-in-shared-view

fix: expand option of hm and mm in shared view
pull/3421/head
Raju Udava 2 years ago committed by GitHub
parent
commit
2da8b6cef7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      packages/nc-gui-v2/components/smartsheet/Gallery.vue
  2. 4
      packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue
  3. 1
      packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue
  4. 42
      packages/nc-gui-v2/composables/useLTARStore.ts
  5. 15
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts
  6. 15
      packages/nocodb/src/lib/meta/api/dataApis/helpers.ts
  7. 17
      packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts
  8. 22
      packages/nocodb/src/lib/meta/helpers/PagedResponse.ts
  9. 58
      packages/nocodb/src/lib/models/Column.ts

4
packages/nc-gui-v2/components/smartsheet/Gallery.vue

@ -203,10 +203,10 @@ openNewRecordFormHook?.on(async () => {
display: block;
font-size: 0;
height: 3px;
opacity: .3;
opacity: 0.3;
outline: none;
padding: 0;
transition: all .5s;
transition: all 0.5s;
width: 100%;
}
.ant-carousel.gallery-carousel :deep(.slick-dots li.slick-active div > div) {

4
packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue

@ -94,14 +94,14 @@ const unlinkRef = async (rec: Record<string, any>) => {
</template>
</div>
<div v-if="!isLocked && isUIAllowed('xcDatatableEditable')" class="flex justify-end gap-1 min-h-[30px] items-center">
<div v-if="!isLocked" class="flex justify-end gap-1 min-h-[30px] items-center">
<MdiArrowExpand
class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500 nc-arrow-expand"
@click="childListDlg = true"
/>
<MdiPlus
v-if="!readOnly"
v-if="!readOnly && isUIAllowed('xcDatatableEditable')"
class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500 nc-plus"
@click="listItemsDlg = true"
/>

1
packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue

@ -101,6 +101,7 @@ const expandedFormRow = ref()
class="!my-4 hover:(!bg-gray-200/50 shadow-md)"
@click="
() => {
if (readonly) return
expandedFormRow = row
expandedFormDlg = true
}

42
packages/nc-gui-v2/composables/useLTARStore.ts

@ -150,19 +150,35 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
try {
if (colOptions.type === 'bt') return
childrenList.value = await $api.dbTableRow.nestedList(
NOCO,
(project?.value?.id || sharedView?.value?.view?.project_id) as string,
meta.value.id,
rowId.value,
colOptions.type as 'mm' | 'hm',
encodeURIComponent(column?.value?.title),
{
limit: String(childrenListPagination.size),
offset: String(childrenListPagination.size * (childrenListPagination.page - 1)),
where: childrenListPagination.query && `(${relatedTablePrimaryValueProp.value},like,${childrenListPagination.query})`,
} as any,
)
if (isPublic) {
childrenList.value = await $api.public.dataNestedList(
sharedView.value?.uuid as string,
rowId.value,
colOptions.type as 'mm' | 'hm',
encodeURIComponent(column?.value?.id),
{
limit: String(childrenListPagination.size),
offset: String(childrenListPagination.size * (childrenListPagination.page - 1)),
where:
childrenListPagination.query && `(${relatedTablePrimaryValueProp.value},like,${childrenListPagination.query})`,
} as any,
)
} else {
childrenList.value = await $api.dbTableRow.nestedList(
NOCO,
(project?.value?.id || sharedView?.value?.view?.project_id) as string,
meta.value.id,
rowId.value,
colOptions.type as 'mm' | 'hm',
encodeURIComponent(column?.value?.title),
{
limit: String(childrenListPagination.size),
offset: String(childrenListPagination.size * (childrenListPagination.page - 1)),
where:
childrenListPagination.query && `(${relatedTablePrimaryValueProp.value},like,${childrenListPagination.query})`,
} as any,
)
}
} catch (e: any) {
message.error(`Failed to load children list: ${await extractSdkResponseErrorMsg(e)}`)
}

15
packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts

@ -4,7 +4,7 @@ import Base from '../../../models/Base';
import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2';
import { PagedResponseImpl } from '../../helpers/PagedResponse';
import ncMetaAclMw from '../../helpers/ncMetaAclMw';
import { getViewAndModelFromRequestByAliasOrId } from './helpers';
import { getColumnByIdOrName, getViewAndModelFromRequestByAliasOrId } from './helpers'
import { NcError } from '../../helpers/catchError';
import apiMetrics from '../../helpers/apiMetrics';
@ -240,19 +240,6 @@ async function relationDataAdd(req, res) {
res.json({ msg: 'success' });
}
async function getColumnByIdOrName(columnNameOrId: string, model: Model) {
const column = (await model.getColumns()).find(
(c) =>
c.title === columnNameOrId ||
c.id === columnNameOrId ||
c.column_name === columnNameOrId
);
if (!column)
NcError.notFound(`Column with id/name '${columnNameOrId}' is not found`);
return column;
}
const router = Router({ mergeParams: true });

15
packages/nocodb/src/lib/meta/api/dataApis/helpers.ts

@ -229,3 +229,18 @@ export async function serializeCellValue({
return value;
}
}
export async function getColumnByIdOrName(columnNameOrId: string, model: Model) {
const column = (await model.getColumns()).find(
(c) =>
c.title === columnNameOrId ||
c.id === columnNameOrId ||
c.column_name === columnNameOrId
);
if (!column)
NcError.notFound(`Column with id/name '${columnNameOrId}' is not found`);
return column;
}

17
packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts

@ -17,6 +17,7 @@ import { mimeIcons } from '../../../utils/mimeTypes';
import slash from 'slash';
import { sanitizeUrlPath } from '../attachmentApis';
import getAst from '../../../db/sql-data-mapper/lib/sql/helpers/getAst';
import { getColumnByIdOrName } from '../dataApis/helpers';
export async function dataList(req: Request, res: Response) {
try {
@ -219,7 +220,10 @@ export async function publicMmList(req: Request, res: Response) {
NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD);
}
const column = await Column.get({ colId: req.params.colId });
const column = await getColumnByIdOrName(
req.params.colId,
await view.getModel()
);
if (column.fk_model_id !== view.fk_model_id)
NcError.badRequest("Column doesn't belongs to the model");
@ -275,7 +279,10 @@ export async function publicHmList(req: Request, res: Response) {
NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD);
}
const column = await Column.get({ colId: req.params.colId });
const column = await getColumnByIdOrName(
req.params.colId,
await view.getModel()
);
if (column.fk_model_id !== view.fk_model_id)
NcError.badRequest("Column doesn't belongs to the model");
@ -317,11 +324,7 @@ export async function publicHmList(req: Request, res: Response) {
id: req.params.rowId,
});
res.json(
new PagedResponseImpl(data, {
totalRows: count,
} as any)
);
res.json(new PagedResponseImpl(data, { ...req.query, count }));
}
const router = Router({ mergeParams: true });

22
packages/nocodb/src/lib/meta/helpers/PagedResponse.ts

@ -5,21 +5,31 @@ const config: any = {
limitMin: Math.max(+process.env.DB_QUERY_LIMIT_MIN || 1, 1),
limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1),
};
export class PagedResponseImpl<T> {
constructor(
list: T[],
args: { limit?: number; offset?: number; count?: number, l?: number, o?: number } = {}
args: {
limit?: number;
offset?: number;
count?: number | string;
l?: number;
o?: number;
} = {}
) {
const limit = Math.max(
Math.min(
args.limit || args.l || config.limitDefault,
config.limitMax
),
Math.min(args.limit || args.l || config.limitDefault, config.limitMax),
config.limitMin
);
const offset = Math.max(+(args.offset || args.o) || 0, 0);
const count = args.count ?? null;
let count = args.count ?? null;
if (count !== null) count = +count;
this.list = list;
if (count !== null) {
this.pageInfo = { totalRows: +count };
this.pageInfo.page = offset ? offset / limit + 1 : 1;

58
packages/nocodb/src/lib/models/Column.ts

@ -232,20 +232,33 @@ export default class Column<T = any> implements ColumnType {
}
case UITypes.MultiSelect: {
if (!column.colOptions?.options) {
const selectColors = [ '#cfdffe', '#d0f1fd', '#c2f5e8', '#ffdaf6', '#ffdce5', '#fee2d5', '#ffeab6', '#d1f7c4', '#ede2fe', '#eeeeee', ];
for (const [i, option] of column.dtxp?.split(',').entries() || [].entries()) {
const selectColors = [
'#cfdffe',
'#d0f1fd',
'#c2f5e8',
'#ffdaf6',
'#ffdce5',
'#fee2d5',
'#ffeab6',
'#d1f7c4',
'#ede2fe',
'#eeeeee',
];
for (const [i, option] of column.dtxp?.split(',').entries() ||
[].entries()) {
await SelectOption.insert(
{
fk_column_id: colId,
title: option.replace(/^'/, '').replace(/'$/, ''),
order: i + 1,
color: selectColors[i % selectColors.length]
color: selectColors[i % selectColors.length],
},
ncMeta
);
}
} else {
for (const [i, option] of column.colOptions.options.entries() || [].entries()) {
for (const [i, option] of column.colOptions.options.entries() ||
[].entries()) {
// Trim end of enum/set
if (column.dt === 'enum' || column.dt === 'set') {
option.title = option.title.trimEnd();
@ -254,7 +267,7 @@ export default class Column<T = any> implements ColumnType {
{
...option,
fk_column_id: colId,
order: i + 1
order: i + 1,
},
ncMeta
);
@ -264,20 +277,33 @@ export default class Column<T = any> implements ColumnType {
}
case UITypes.SingleSelect: {
if (!column.colOptions?.options) {
const selectColors = [ '#cfdffe', '#d0f1fd', '#c2f5e8', '#ffdaf6', '#ffdce5', '#fee2d5', '#ffeab6', '#d1f7c4', '#ede2fe', '#eeeeee', ];
for (const [i, option] of column.dtxp?.split(',').entries() || [].entries()) {
const selectColors = [
'#cfdffe',
'#d0f1fd',
'#c2f5e8',
'#ffdaf6',
'#ffdce5',
'#fee2d5',
'#ffeab6',
'#d1f7c4',
'#ede2fe',
'#eeeeee',
];
for (const [i, option] of column.dtxp?.split(',').entries() ||
[].entries()) {
await SelectOption.insert(
{
fk_column_id: colId,
title: option.replace(/^'/, '').replace(/'$/, ''),
order: i + 1,
color: selectColors[i % selectColors.length]
color: selectColors[i % selectColors.length],
},
ncMeta
);
}
} else {
for (const [i, option] of column.colOptions.options.entries() || [].entries()) {
for (const [i, option] of column.colOptions.options.entries() ||
[].entries()) {
// Trim end of enum/set
if (column.dt === 'enum' || column.dt === 'set') {
option.title = option.title.trimEnd();
@ -286,7 +312,7 @@ export default class Column<T = any> implements ColumnType {
{
...option,
fk_column_id: colId,
order: i + 1
order: i + 1,
},
ncMeta
);
@ -507,12 +533,14 @@ export default class Column<T = any> implements ColumnType {
MetaTable.COLUMNS,
colId
);
try {
colData.meta = JSON.parse(colData.meta);
} catch {
colData.meta = {};
if (colData) {
try {
colData.meta = JSON.parse(colData.meta);
} catch {
colData.meta = {};
}
await NocoCache.set(`${CacheScope.COLUMN}:${colId}`, colData);
}
await NocoCache.set(`${CacheScope.COLUMN}:${colId}`, colData);
}
if (colData) {
const column = new Column(colData);

Loading…
Cancel
Save