Move table renderers to components [SCI-11009]

This commit is contained in:
Anton 2024-09-03 13:22:57 +02:00
parent 88462de1d5
commit f8fd07695f
17 changed files with 264 additions and 125 deletions

View file

@ -0,0 +1,14 @@
<template>
<i v-if="params.data.default" class="sn-icon sn-icon-approval"></i>
<span v-else></span>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
}
};
</script>

View file

@ -0,0 +1,17 @@
<template>
<span>
<span v-html="params.data.icon_url"></span>
<span>{{ params.data.format }}</span>
</span>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
}
};
</script>

View file

@ -0,0 +1,16 @@
<template>
<a :href="params.data.urls.show" :title="params.data.name">
{{ params.data.name }}
</a>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
}
};
</script>

View file

@ -30,28 +30,34 @@ import axios from '../../packs/custom_axios.js';
import DataTable from '../shared/datatable/table.vue';
import DeleteModal from '../shared/confirmation_modal.vue';
import NameRenderer from './renderers/name.vue';
import DefaultRenderer from './renderers/default.vue';
import FormatRenderer from './renderers/format.vue';
export default {
name: 'LabelTemplatesTable',
components: {
DataTable,
DeleteModal,
NameRenderer,
DefaultRenderer,
FormatRenderer
},
props: {
dataSource: {
type: String,
required: true,
required: true
},
actionsUrl: {
type: String,
required: true,
required: true
},
createUrl: {
type: String,
type: String
},
syncFluicsUrl: {
type: String,
},
type: String
}
},
data() {
return {
@ -60,40 +66,40 @@ export default {
{
field: 'default',
headerName: this.i18n.t('label_templates.index.default_label'),
cellRenderer: this.defaultRenderer,
sortable: true,
cellRenderer: 'DefaultRenderer',
sortable: true
}, {
field: 'name',
headerName: this.i18n.t('label_templates.index.thead_name'),
cellRenderer: this.labelNameRenderer,
sortable: true,
cellRenderer: 'NameRenderer',
sortable: true
}, {
field: 'format',
headerName: this.i18n.t('label_templates.index.format'),
sortable: true,
cellRenderer: ({ data: { format, icon_url: iconUrl } }) => `<span>${iconUrl}</span> <span>${format}</span>`
cellRenderer: 'FormatRenderer'
}, {
field: 'description',
headerName: this.i18n.t('label_templates.index.description'),
sortable: true,
sortable: true
}, {
field: 'modified_by',
headerName: this.i18n.t('label_templates.index.updated_by'),
sortable: true,
sortable: true
}, {
field: 'updated_at',
headerName: this.i18n.t('label_templates.index.updated_at'),
sortable: true,
sortable: true
}, {
field: 'created_by',
headerName: this.i18n.t('label_templates.index.created_by'),
sortable: true,
sortable: true
}, {
field: 'created_at',
headerName: this.i18n.t('label_templates.index.created_at'),
sortable: true,
},
],
sortable: true
}
]
};
},
computed: {
@ -106,7 +112,7 @@ export default {
label: this.i18n.t('label_templates.index.toolbar.new'),
type: 'emit',
path: this.createUrl,
buttonStyle: 'btn btn-primary',
buttonStyle: 'btn btn-primary'
});
}
if (this.syncFluicsUrl) {
@ -121,21 +127,11 @@ export default {
}
return {
left,
right: [],
right: []
};
},
}
},
methods: {
labelNameRenderer(params) {
const editUrl = params.data.urls.show;
return `<a href="${editUrl}" title="${params.data.name}">
${params.data.name}
</a>`;
},
defaultRenderer(params) {
const defaultSelected = params.data.default;
return defaultSelected ? '<i class="sn-icon sn-icon-approval"></i>' : '';
},
setDefault(action) {
axios.post(action.path).then((response) => {
this.reloadingTable = true;
@ -175,8 +171,8 @@ export default {
HelperModule.flashAlertMsg(error.response.data.error, 'danger');
});
}
},
},
}
}
};
</script>

View file

@ -16,6 +16,7 @@
:hiddenDataMessage="i18n.t('experiments.empty_state.no_active_modules_archived_branch')"
scrollMode="infinite"
@tableReloaded="reloadingTable = false"
@reloadTable="reloadingTable = true"
@create="newModalOpen = true"
@edit="edit"
@move="move"
@ -56,6 +57,9 @@
import axios from '../../packs/custom_axios.js';
import DataTable from '../shared/datatable/table.vue';
import ConfirmationModal from '../shared/confirmation_modal.vue';
import NameRenderer from './renderers/name.vue';
import ResultsRenderer from './renderers/results.vue';
import StatusRenderer from './renderers/status.vue';
import DueDateRenderer from './renderers/due_date.vue';
import DesignatedUsers from './renderers/designated_users.vue';
import TagsModal from './modals/tags.vue';
@ -77,7 +81,10 @@ export default {
NewModal,
EditModal,
MoveModal,
AccessModal
AccessModal,
NameRenderer,
ResultsRenderer,
StatusRenderer
},
props: {
dataSource: { type: String, required: true },
@ -115,7 +122,7 @@ export default {
field: 'name',
headerName: this.i18n.t('experiments.table.column.task_name_html'),
sortable: true,
cellRenderer: this.nameRenderer
cellRenderer: NameRenderer
},
{
field: 'code',
@ -133,7 +140,7 @@ export default {
field: 'results',
headerName: this.i18n.t('experiments.table.column.results_html'),
sortable: true,
cellRenderer: this.resultsRenderer
cellRenderer: ResultsRenderer
},
{
field: 'age',
@ -144,7 +151,7 @@ export default {
field: 'status',
headerName: this.i18n.t('experiments.table.column.status_html'),
sortable: true,
cellRenderer: this.statusRenderer,
cellRenderer: StatusRenderer,
minWidth: 120
}
];
@ -321,53 +328,6 @@ export default {
roles_path: this.userRolesUrl
};
},
checkProvisioning(params) {
if (params.data.provisioning_status === 'done') return;
axios.get(params.data.urls.provisioning_status).then((response) => {
const provisioningStatus = response.data.provisioning_status;
if (provisioningStatus === 'done') {
this.reloadingTable = true;
} else {
setTimeout(() => {
this.checkProvisioning(params);
}, 5000);
}
});
},
// Renderers
nameRenderer(params) {
const { name, urls } = params.data;
const provisioningStatus = params.data.provisioning_status;
if (provisioningStatus === 'in_progress') {
setTimeout(() => {
this.checkProvisioning(params);
}, 5000);
return `
<span class="flex gap-2 items-center">
<div title="${this.i18n.t('experiments.duplicate_tasks.duplicating')}"
class="loading-overlay w-6 h-6 !relative shrink-0" data-toggle="tooltip" data-placement="right"></div>
<span class="truncate">${name}</span>
</span>`;
}
return `<a href="${urls.show}" title="${name}" ><span class="truncate">${name}</span></a>`;
},
statusRenderer(params) {
const { status } = params.data;
return `<span
class="px-2 py-1 border border-solid rounded truncate ${!status.light_color ? 'text-sn-white' : ''}"
style="background-color: ${status.color};"
>
${status.name}
</span>`;
},
resultsRenderer(params) {
const { results, urls } = params.data;
return `<a href="${urls.results}" >${results}</a>`;
},
usersFilterRenderer(option) {
return `<div class="flex items-center gap-2">
<img src="${option[2].avatar_url}" class="rounded-full w-6 h-6" />

View file

@ -0,0 +1,49 @@
<template>
<template v-if="params.data.provisioning_status === 'in_progress'">
<span class="flex gap-2 items-center">
<div :title="this.i18n.t('experiments.duplicate_tasks.duplicating')"
class="loading-overlay w-6 h-6 !relative shrink-0" data-toggle="tooltip" data-placement="right"></div>
<span class="truncate">{{ params.data.name }}</span>
</span>
</template>
<template v-else>
<a :href="params.data.urls.show" :title="params.data.name" >
<span class="truncate">{{ params.data.name }}</span>
</a>
</template>
</template>
<script>
import axios from '../../../packs/custom_axios.js';
export default {
name: 'NameRenderer',
props: {
params: {
required: true
}
},
created() {
if (this.params.data.provisioning_status === 'in_progress') {
setTimeout(() => {
this.checkProvisioning();
}, 5000);
}
},
methods: {
checkProvisioning() {
if (this.params.data.provisioning_status === 'done') return;
axios.get(this.params.data.urls.provisioning_status).then((response) => {
const provisioningStatus = response.data.provisioning_status;
if (provisioningStatus === 'done') {
this.params.dtComponent.$emit('reloadTable', null, [this.params.data]);
} else {
setTimeout(() => {
this.checkProvisioning();
}, 5000);
}
});
}
}
};
</script>

View file

@ -0,0 +1,14 @@
<template>
<a :href="params.data.urls.results" >{{ params.data.results }}</a>
</template>
<script>
export default {
name: 'ResultsRenderer',
props: {
params: {
required: true
}
}
};
</script>

View file

@ -0,0 +1,20 @@
<template>
<span
class="px-2 py-1 border border-solid rounded truncate"
:class="{'text-sn-white' : !params.data.status.light_color}"
:style="{'background-color': params.data.status.color}"
>
{{ params.data.status.name }}
</span>
</template>
<script>
export default {
name: 'StatusRenderer',
props: {
params: {
required: true
}
}
};
</script>

View file

@ -68,6 +68,7 @@ import axios from '../../packs/custom_axios.js';
import DataTable from '../shared/datatable/table.vue';
import UsersRenderer from './renderers/users.vue';
import NameRenderer from './renderers/name.vue';
import CommentsRenderer from '../shared/datatable/renderers/comments.vue';
import ProjectCard from './card.vue';
import ConfirmationModal from '../shared/confirmation_modal.vue';
@ -84,6 +85,7 @@ export default {
components: {
DataTable,
UsersRenderer,
NameRenderer,
ProjectCard,
ConfirmationModal,
EditProjectModal,
@ -129,7 +131,7 @@ export default {
flex: 1,
headerName: this.i18n.t('projects.index.card.name'),
sortable: true,
cellRenderer: this.nameRenderer
cellRenderer: 'NameRenderer'
},
{
field: 'code',
@ -252,16 +254,6 @@ export default {
<span title="${option[1]}" class="truncate">${option[1]}</span>
</div>`;
},
nameRenderer(params) {
const showUrl = params.data.urls.show;
return `<a href="${showUrl}"
class="flex items-center gap-1 hover:no-underline
${!showUrl ? 'pointer-events-none text-sn-grey' : ''}"
title="${params.data.name}">
${params.data.folder ? '<i class="sn-icon mini sn-icon-mini-folder-left"></i>' : ''}
<span class="truncate">${params.data.name} </span>
</a>`;
},
openComments(_params, rows) {
$(this.$refs.commentButton).data('objectId', rows[0].id);
this.$refs.commentButton.click();

View file

@ -0,0 +1,21 @@
<template>
<a :href="params.data.urls.show"
class="flex items-center gap-1 hover:no-underline"
:class="{
'pointer-events-none text-sn-grey': !params.data.urls.show
}"
:title="params.data.name">
<i v-if="params.data.folder" class="sn-icon mini sn-icon-mini-folder-left"></i>
<span class="truncate">{{ params.data.name }}</span>
</a>
</template>
<script>
export default {
name: 'NameRenderer',
props: {
params: {
required: true
}
}
};
</script>

View file

@ -19,8 +19,8 @@ export default {
name: 'UsersRenderer',
props: {
params: {
required: true,
},
required: true
}
},
computed: {
users() {

View file

@ -0,0 +1,21 @@
<template>
<a v-if="params.data.urls.show"
:href="params.data.urls.show"
:title="params.data.name">
{{ params.data.name }}
</a>
<span v-else class="text-sn-grey" :title="params.data.name">
{{ params.data.name }}
</span>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
}
};
</script>

View file

@ -42,6 +42,7 @@ import axios from '../../packs/custom_axios.js';
import DataTable from '../shared/datatable/table.vue';
import UsersRenderer from '../projects/renderers/users.vue';
import NameRenderer from './renderers/name.vue';
import NewProtocolModal from './modals/new.vue';
import AccessModal from '../shared/access_modal/modal.vue';
import KeywordsRenderer from './renderers/keywords.vue';
@ -55,6 +56,7 @@ export default {
components: {
DataTable,
UsersRenderer,
NameRenderer,
NewProtocolModal,
AccessModal,
KeywordsRenderer,
@ -116,7 +118,7 @@ export default {
headerName: this.i18n.t('protocols.index.thead.name'),
sortable: true,
notSelectable: true,
cellRenderer: this.nameRenderer
cellRenderer: 'NameRenderer'
},
{
field: 'code',
@ -337,14 +339,6 @@ export default {
linkedMyModules(_event, rows) {
[this.linkedMyModulesModalObject] = rows;
},
// renderers
nameRenderer(params) {
const { urls, name } = params.data;
if (urls.show) {
return `<a href="${urls.show}" title="${name}">${name}</a>`;
}
return `<span class="text-sn-grey" title="${name}">${name}</span>`;
},
usersFilterRenderer(option) {
return `<div class="flex items-center gap-2">
<img src="${option[2].avatar_url}" class="rounded-full w-6 h-6" />

View file

@ -0,0 +1,16 @@
<template>
<span :title="params.data.name">
{{ params.data.name }}
</span>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
}
};
</script>

View file

@ -43,6 +43,7 @@ import axios from '../../packs/custom_axios.js';
import DataTable from '../shared/datatable/table.vue';
import DocxRenderer from './renderers/docx.vue';
import PdfRenderer from './renderers/pdf.vue';
import NameRenderer from './renderers/name.vue';
import ConfirmationModal from '../shared/confirmation_modal.vue';
import SaveToInventoryModal from './modals/save_to_inventory.vue';
import UpdateReportModal from './modals/update.vue';
@ -60,6 +61,7 @@ export default {
DataTable,
DocxRenderer,
PdfRenderer,
NameRenderer,
ConfirmationModal,
SaveToInventoryModal,
UpdateReportModal
@ -108,7 +110,7 @@ export default {
field: 'name',
headerName: this.i18n.t('projects.reports.index.thead_name'),
sortable: true,
cellRenderer: ({ data: { name } }) => `<span title="${name}">${name}</span>`
cellRenderer: 'NameRenderer'
}, {
field: 'code',
headerName: this.i18n.t('projects.reports.index.thead_id'),

View file

@ -0,0 +1,22 @@
<template>
<a class="hover:no-underline flex items-center gap-1"
:title="params.data.name"
:href="params.data.urls.show"
>
<span class="truncate">
<i v-if="params.data.shared || params.data.ishared" class="fas fa-users"></i>
{{ params.data.name }}
</span>
</a>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
}
};
</script>

View file

@ -68,6 +68,7 @@ import EditRepositoryModal from './modals/edit.vue';
import DuplicateRepositoryModal from './modals/duplicate.vue';
import ShareRepositoryModal from './modals/share.vue';
import DataTable from '../shared/datatable/table.vue';
import NameRenderer from './renderers/name.vue';
export default {
name: 'RepositoriesTable',
@ -78,7 +79,8 @@ export default {
NewRepositoryModal,
EditRepositoryModal,
DuplicateRepositoryModal,
ShareRepositoryModal
ShareRepositoryModal,
NameRenderer
},
props: {
dataSource: {
@ -138,7 +140,7 @@ export default {
headerName: this.i18n.t('libraries.index.table.name'),
sortable: true,
notSelectable: true,
cellRenderer: this.nameRenderer
cellRenderer: 'NameRenderer'
},
{
field: 'code',
@ -277,23 +279,6 @@ export default {
share(_event, rows) {
const [repository] = rows;
this.shareRepository = repository;
},
// Renderers
nameRenderer(params) {
const {
name,
urls,
shared,
ishared
} = params.data;
let sharedIcon = '';
if (shared || ishared) {
sharedIcon = '<i class="fas fa-users"></i>';
}
return `<a class="hover:no-underline flex items-center gap-1"
title="${name}" href="${urls.show}">
<span class="truncate">${sharedIcon}${name}</span>
</a>`;
}
}
};