summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/admin/users/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/admin/users/components')
-rw-r--r--app/assets/javascripts/admin/users/components/actions/activate.vue44
-rw-r--r--app/assets/javascripts/admin/users/components/actions/approve.vue21
-rw-r--r--app/assets/javascripts/admin/users/components/actions/block.vue53
-rw-r--r--app/assets/javascripts/admin/users/components/actions/deactivate.vue60
-rw-r--r--app/assets/javascripts/admin/users/components/actions/delete.vue25
-rw-r--r--app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue25
-rw-r--r--app/assets/javascripts/admin/users/components/actions/index.js21
-rw-r--r--app/assets/javascripts/admin/users/components/actions/reject.vue21
-rw-r--r--app/assets/javascripts/admin/users/components/actions/shared/shared_delete_action.vue43
-rw-r--r--app/assets/javascripts/admin/users/components/actions/unblock.vue44
-rw-r--r--app/assets/javascripts/admin/users/components/actions/unlock.vue42
-rw-r--r--app/assets/javascripts/admin/users/components/usage_ping_disabled.vue48
-rw-r--r--app/assets/javascripts/admin/users/components/user_actions.vue119
-rw-r--r--app/assets/javascripts/admin/users/components/user_avatar.vue30
-rw-r--r--app/assets/javascripts/admin/users/components/user_date.vue29
-rw-r--r--app/assets/javascripts/admin/users/components/users_table.vue18
16 files changed, 635 insertions, 8 deletions
diff --git a/app/assets/javascripts/admin/users/components/actions/activate.vue b/app/assets/javascripts/admin/users/components/actions/activate.vue
new file mode 100644
index 00000000000..99c260bf11e
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/activate.vue
@@ -0,0 +1,44 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ modalAttributes() {
+ return {
+ 'data-path': this.path,
+ 'data-method': 'put',
+ 'data-modal-attributes': JSON.stringify({
+ title: sprintf(s__('AdminUsers|Activate user %{username}?'), {
+ username: this.username,
+ }),
+ message: s__('AdminUsers|You can always deactivate their account again if needed.'),
+ okVariant: 'confirm',
+ okTitle: s__('AdminUsers|Activate'),
+ }),
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="js-confirm-modal-button" v-bind="{ ...modalAttributes }">
+ <gl-dropdown-item>
+ <slot></slot>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/approve.vue b/app/assets/javascripts/admin/users/components/actions/approve.vue
new file mode 100644
index 00000000000..6fc43c246ea
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/approve.vue
@@ -0,0 +1,21 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown-item :href="path" data-method="put">
+ <slot></slot>
+ </gl-dropdown-item>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/block.vue b/app/assets/javascripts/admin/users/components/actions/block.vue
new file mode 100644
index 00000000000..68dfefe14c2
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/block.vue
@@ -0,0 +1,53 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
+
+// TODO: To be replaced with <template> content in https://gitlab.com/gitlab-org/gitlab/-/issues/320922
+const messageHtml = `
+ <p>${s__('AdminUsers|Blocking user has the following effects:')}</p>
+ <ul>
+ <li>${s__('AdminUsers|User will not be able to login')}</li>
+ <li>${s__('AdminUsers|User will not be able to access git repositories')}</li>
+ <li>${s__('AdminUsers|Personal projects will be left')}</li>
+ <li>${s__('AdminUsers|Owned groups will be left')}</li>
+ </ul>
+`;
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ modalAttributes() {
+ return {
+ 'data-path': this.path,
+ 'data-method': 'put',
+ 'data-modal-attributes': JSON.stringify({
+ title: sprintf(s__('AdminUsers|Block user %{username}?'), { username: this.username }),
+ okVariant: 'confirm',
+ okTitle: s__('AdminUsers|Block'),
+ messageHtml,
+ }),
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="js-confirm-modal-button" v-bind="{ ...modalAttributes }">
+ <gl-dropdown-item>
+ <slot></slot>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/deactivate.vue b/app/assets/javascripts/admin/users/components/actions/deactivate.vue
new file mode 100644
index 00000000000..7e0c17ba296
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/deactivate.vue
@@ -0,0 +1,60 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
+
+// TODO: To be replaced with <template> content in https://gitlab.com/gitlab-org/gitlab/-/issues/320922
+const messageHtml = `
+ <p>${s__('AdminUsers|Deactivating a user has the following effects:')}</p>
+ <ul>
+ <li>${s__('AdminUsers|The user will be logged out')}</li>
+ <li>${s__('AdminUsers|The user will not be able to access git repositories')}</li>
+ <li>${s__('AdminUsers|The user will not be able to access the API')}</li>
+ <li>${s__('AdminUsers|The user will not receive any notifications')}</li>
+ <li>${s__('AdminUsers|The user will not be able to use slash commands')}</li>
+ <li>${s__(
+ 'AdminUsers|When the user logs back in, their account will reactivate as a fully active account',
+ )}</li>
+ <li>${s__('AdminUsers|Personal projects, group and user history will be left intact')}</li>
+ </ul>
+`;
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ modalAttributes() {
+ return {
+ 'data-path': this.path,
+ 'data-method': 'put',
+ 'data-modal-attributes': JSON.stringify({
+ title: sprintf(s__('AdminUsers|Deactivate user %{username}?'), {
+ username: this.username,
+ }),
+ okVariant: 'confirm',
+ okTitle: s__('AdminUsers|Deactivate'),
+ messageHtml,
+ }),
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="js-confirm-modal-button" v-bind="{ ...modalAttributes }">
+ <gl-dropdown-item>
+ <slot></slot>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/delete.vue b/app/assets/javascripts/admin/users/components/actions/delete.vue
new file mode 100644
index 00000000000..725d3dbf388
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/delete.vue
@@ -0,0 +1,25 @@
+<script>
+import SharedDeleteAction from './shared/shared_delete_action.vue';
+
+export default {
+ components: {
+ SharedDeleteAction,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ paths: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <shared-delete-action modal-type="delete" :username="username" :paths="paths">
+ <slot></slot>
+ </shared-delete-action>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue b/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue
new file mode 100644
index 00000000000..0ae15bfbebb
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/delete_with_contributions.vue
@@ -0,0 +1,25 @@
+<script>
+import SharedDeleteAction from './shared/shared_delete_action.vue';
+
+export default {
+ components: {
+ SharedDeleteAction,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ paths: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <shared-delete-action modal-type="delete-with-contributions" :username="username" :paths="paths">
+ <slot></slot>
+ </shared-delete-action>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/index.js b/app/assets/javascripts/admin/users/components/actions/index.js
new file mode 100644
index 00000000000..e34b01346b9
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/index.js
@@ -0,0 +1,21 @@
+import Activate from './activate.vue';
+import Approve from './approve.vue';
+import Block from './block.vue';
+import Deactivate from './deactivate.vue';
+import Delete from './delete.vue';
+import DeleteWithContributions from './delete_with_contributions.vue';
+import Reject from './reject.vue';
+import Unblock from './unblock.vue';
+import Unlock from './unlock.vue';
+
+export default {
+ Activate,
+ Approve,
+ Block,
+ Deactivate,
+ Delete,
+ DeleteWithContributions,
+ Unblock,
+ Unlock,
+ Reject,
+};
diff --git a/app/assets/javascripts/admin/users/components/actions/reject.vue b/app/assets/javascripts/admin/users/components/actions/reject.vue
new file mode 100644
index 00000000000..a80c1ff5458
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/reject.vue
@@ -0,0 +1,21 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown-item :href="path" data-method="delete">
+ <slot></slot>
+ </gl-dropdown-item>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/shared/shared_delete_action.vue b/app/assets/javascripts/admin/users/components/actions/shared/shared_delete_action.vue
new file mode 100644
index 00000000000..9107d9ccdd9
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/shared/shared_delete_action.vue
@@ -0,0 +1,43 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ paths: {
+ type: Object,
+ required: true,
+ },
+ modalType: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ modalAttributes() {
+ return {
+ 'data-block-user-url': this.paths.block,
+ 'data-delete-user-url': this.paths.delete,
+ 'data-gl-modal-action': this.modalType,
+ 'data-username': this.username,
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="js-delete-user-modal-button" v-bind="{ ...modalAttributes }">
+ <gl-dropdown-item>
+ <span class="gl-text-red-500">
+ <slot></slot>
+ </span>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/unblock.vue b/app/assets/javascripts/admin/users/components/actions/unblock.vue
new file mode 100644
index 00000000000..f2b501caf09
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/unblock.vue
@@ -0,0 +1,44 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ modalAttributes() {
+ return {
+ 'data-path': this.path,
+ 'data-method': 'put',
+ 'data-modal-attributes': JSON.stringify({
+ title: sprintf(s__('AdminUsers|Unblock user %{username}?'), { username: this.username }),
+ message: s__(
+ 'AdminUsers|You can always unblock their account, their data will remain intact.',
+ ),
+ okVariant: 'confirm',
+ okTitle: s__('AdminUsers|Unblock'),
+ }),
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="js-confirm-modal-button" v-bind="{ ...modalAttributes }">
+ <gl-dropdown-item>
+ <slot></slot>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/actions/unlock.vue b/app/assets/javascripts/admin/users/components/actions/unlock.vue
new file mode 100644
index 00000000000..294aaade7c1
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/actions/unlock.vue
@@ -0,0 +1,42 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+import { sprintf, s__, __ } from '~/locale';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ username: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ modalAttributes() {
+ return {
+ 'data-path': this.path,
+ 'data-method': 'put',
+ 'data-modal-attributes': JSON.stringify({
+ title: sprintf(s__('AdminUsers|Unlock user %{username}?'), { username: this.username }),
+ message: __('Are you sure?'),
+ okVariant: 'confirm',
+ okTitle: s__('AdminUsers|Unlock'),
+ }),
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="js-confirm-modal-button" v-bind="{ ...modalAttributes }">
+ <gl-dropdown-item>
+ <slot></slot>
+ </gl-dropdown-item>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/usage_ping_disabled.vue b/app/assets/javascripts/admin/users/components/usage_ping_disabled.vue
new file mode 100644
index 00000000000..5da38495010
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/usage_ping_disabled.vue
@@ -0,0 +1,48 @@
+<script>
+import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlEmptyState,
+ GlSprintf,
+ GlLink,
+ },
+ inject: {
+ svgPath: {
+ default: '',
+ },
+ docsLink: {
+ default: '',
+ },
+ primaryButtonPath: {
+ default: '',
+ },
+ },
+};
+</script>
+<template>
+ <gl-empty-state
+ class="js-empty-state"
+ :title="__('Activate user activity analysis')"
+ :svg-path="svgPath"
+ :primary-button-text="__('Turn on usage ping')"
+ :primary-button-link="primaryButtonPath"
+ >
+ <template #description>
+ <gl-sprintf
+ :message="
+ __(
+ 'Turn on %{strongStart}usage ping%{strongEnd} to activate analysis of user activity, known as %{docLinkStart}Cohorts%{docLinkEnd}.',
+ )
+ "
+ >
+ <template #docLink="{ content }">
+ <gl-link :href="docsLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #strong="{ content }"
+ ><strong>{{ content }}</strong></template
+ >
+ </gl-sprintf>
+ </template>
+ </gl-empty-state>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/user_actions.vue b/app/assets/javascripts/admin/users/components/user_actions.vue
new file mode 100644
index 00000000000..e92c97b54a3
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/user_actions.vue
@@ -0,0 +1,119 @@
+<script>
+import {
+ GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlDropdownDivider,
+} from '@gitlab/ui';
+import { convertArrayToCamelCase } from '~/lib/utils/common_utils';
+import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
+import { I18N_USER_ACTIONS } from '../constants';
+import { generateUserPaths } from '../utils';
+import Actions from './actions';
+
+export default {
+ components: {
+ GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlDropdownDivider,
+ ...Actions,
+ },
+ props: {
+ user: {
+ type: Object,
+ required: true,
+ },
+ paths: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ userActions() {
+ return convertArrayToCamelCase(this.user.actions);
+ },
+ dropdownActions() {
+ return this.userActions.filter((a) => a !== 'edit');
+ },
+ dropdownDeleteActions() {
+ return this.dropdownActions.filter((a) => a.includes('delete'));
+ },
+ dropdownSafeActions() {
+ return this.dropdownActions.filter((a) => !this.dropdownDeleteActions.includes(a));
+ },
+ hasDropdownActions() {
+ return this.dropdownActions.length > 0;
+ },
+ hasDeleteActions() {
+ return this.dropdownDeleteActions.length > 0;
+ },
+ hasEditAction() {
+ return this.userActions.includes('edit');
+ },
+ userPaths() {
+ return generateUserPaths(this.paths, this.user.username);
+ },
+ },
+ methods: {
+ isLdapAction(action) {
+ return action === 'ldapBlocked';
+ },
+ getActionComponent(action) {
+ return Actions[capitalizeFirstCharacter(action)];
+ },
+ },
+ i18n: I18N_USER_ACTIONS,
+};
+</script>
+
+<template>
+ <div class="gl-display-flex gl-justify-content-end">
+ <gl-button v-if="hasEditAction" data-testid="edit" :href="userPaths.edit">{{
+ $options.i18n.edit
+ }}</gl-button>
+
+ <gl-dropdown
+ v-if="hasDropdownActions"
+ data-testid="actions"
+ right
+ class="gl-ml-2"
+ icon="settings"
+ >
+ <gl-dropdown-section-header>{{ $options.i18n.settings }}</gl-dropdown-section-header>
+
+ <template v-for="action in dropdownSafeActions">
+ <component
+ :is="getActionComponent(action)"
+ v-if="getActionComponent(action)"
+ :key="action"
+ :path="userPaths[action]"
+ :username="user.name"
+ :data-testid="action"
+ >
+ {{ $options.i18n[action] }}
+ </component>
+ <gl-dropdown-item v-else-if="isLdapAction(action)" :key="action" :data-testid="action">
+ {{ $options.i18n[action] }}
+ </gl-dropdown-item>
+ </template>
+
+ <gl-dropdown-divider v-if="hasDeleteActions" />
+
+ <template v-for="action in dropdownDeleteActions">
+ <component
+ :is="getActionComponent(action)"
+ v-if="getActionComponent(action)"
+ :key="action"
+ :paths="userPaths"
+ :username="user.name"
+ :data-testid="`delete-${action}`"
+ >
+ {{ $options.i18n[action] }}
+ </component>
+ </template>
+ </gl-dropdown>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/user_avatar.vue b/app/assets/javascripts/admin/users/components/user_avatar.vue
index 4f79c4fd451..ce22595609d 100644
--- a/app/assets/javascripts/admin/users/components/user_avatar.vue
+++ b/app/assets/javascripts/admin/users/components/user_avatar.vue
@@ -1,12 +1,16 @@
<script>
-import { GlAvatarLink, GlAvatarLabeled, GlBadge } from '@gitlab/ui';
-import { USER_AVATAR_SIZE } from '../constants';
+import { GlAvatarLabeled, GlBadge, GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { truncate } from '~/lib/utils/text_utility';
+import { USER_AVATAR_SIZE, LENGTH_OF_USER_NOTE_TOOLTIP } from '../constants';
export default {
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
components: {
- GlAvatarLink,
GlAvatarLabeled,
GlBadge,
+ GlIcon,
},
props: {
user: {
@@ -22,16 +26,23 @@ export default {
adminUserHref() {
return this.adminUserPath.replace('id', this.user.username);
},
+ adminUserMailto() {
+ // NOTE: 'mailto:' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26#possible-false-positives
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ return `mailto:${this.user.email}`;
+ },
+ userNoteShort() {
+ return truncate(this.user.note, LENGTH_OF_USER_NOTE_TOOLTIP);
+ },
},
USER_AVATAR_SIZE,
};
</script>
<template>
- <gl-avatar-link
+ <div
v-if="user"
- class="js-user-link"
- :href="adminUserHref"
+ class="js-user-link gl-display-inline-block"
:data-user-id="user.id"
:data-username="user.username"
>
@@ -40,8 +51,13 @@ export default {
:src="user.avatarUrl"
:label="user.name"
:sub-label="user.email"
+ :label-link="adminUserHref"
+ :sub-label-link="adminUserMailto"
>
<template #meta>
+ <div v-if="user.note" class="gl-text-gray-500 gl-p-1">
+ <gl-icon v-gl-tooltip="userNoteShort" name="document" />
+ </div>
<div v-for="(badge, idx) in user.badges" :key="idx" class="gl-p-1">
<gl-badge class="gl-display-flex!" size="sm" :variant="badge.variant">{{
badge.text
@@ -49,5 +65,5 @@ export default {
</div>
</template>
</gl-avatar-labeled>
- </gl-avatar-link>
+ </div>
</template>
diff --git a/app/assets/javascripts/admin/users/components/user_date.vue b/app/assets/javascripts/admin/users/components/user_date.vue
new file mode 100644
index 00000000000..38dddbf72c2
--- /dev/null
+++ b/app/assets/javascripts/admin/users/components/user_date.vue
@@ -0,0 +1,29 @@
+<script>
+import { formatDate } from '~/lib/utils/datetime_utility';
+import { __ } from '~/locale';
+import { SHORT_DATE_FORMAT } from '../constants';
+
+export default {
+ props: {
+ date: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ computed: {
+ formattedDate() {
+ const { date } = this;
+ if (date === null) {
+ return __('Never');
+ }
+ return formatDate(new Date(date), SHORT_DATE_FORMAT);
+ },
+ },
+};
+</script>
+<template>
+ <span>
+ {{ formattedDate }}
+ </span>
+</template>
diff --git a/app/assets/javascripts/admin/users/components/users_table.vue b/app/assets/javascripts/admin/users/components/users_table.vue
index 15e31935a4c..8962068601c 100644
--- a/app/assets/javascripts/admin/users/components/users_table.vue
+++ b/app/assets/javascripts/admin/users/components/users_table.vue
@@ -1,7 +1,9 @@
<script>
import { GlTable } from '@gitlab/ui';
import { __ } from '~/locale';
+import UserActions from './user_actions.vue';
import UserAvatar from './user_avatar.vue';
+import UserDate from './user_date.vue';
const DEFAULT_TH_CLASSES =
'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-100! gl-p-5! gl-border-b-1!';
@@ -11,6 +13,8 @@ export default {
components: {
GlTable,
UserAvatar,
+ UserActions,
+ UserDate,
},
props: {
users: {
@@ -62,7 +66,19 @@ export default {
stacked="md"
>
<template #cell(name)="{ item: user }">
- <UserAvatar :user="user" :admin-user-path="paths.adminUser" />
+ <user-avatar :user="user" :admin-user-path="paths.adminUser" />
+ </template>
+
+ <template #cell(createdAt)="{ item: { createdAt } }">
+ <user-date :date="createdAt" />
+ </template>
+
+ <template #cell(lastActivityOn)="{ item: { lastActivityOn } }">
+ <user-date :date="lastActivityOn" show-never />
+ </template>
+
+ <template #cell(settings)="{ item: user }">
+ <user-actions :user="user" :paths="paths" />
</template>
</gl-table>
</div>