Skip to content
代码片段 群组 项目
提交 3826788d 编辑于 作者: Peter Hegman's avatar Peter Hegman
浏览文件

Refactor project GraphQL formatter to not override `name`

It is confusing to set `name` to `nameWithNamespace`. We should just
directly use `nameWithNamespace` when needed.
上级 54d97f57
No related branches found
No related tags found
2 合并请求!3031Merge per-main-jh to main-jh by luzhiyuan,!3030Merge per-main-jh to main-jh
显示
87 个添加100 个删除
......@@ -11,7 +11,7 @@ import { formatGroups, timestampType } from '~/organizations/shared/utils';
import {
renderDeleteSuccessToast,
deleteParams,
} from 'ee_else_ce/vue_shared/components/resource_lists/utils';
} from 'ee_else_ce/vue_shared/components/groups_list/utils';
import groupsQuery from '../graphql/queries/groups.query.graphql';
import { SORT_ITEM_NAME, SORT_DIRECTION_ASC } from '../constants';
import NewGroupButton from './new_group_button.vue';
......
import toast from '~/vue_shared/plugins/global_toast';
import { sprintf, __ } from '~/locale';
export const renderDeleteSuccessToast = (item, type) => {
export const renderDeleteSuccessToast = (group) => {
toast(
sprintf(__("%{type} '%{name}' is being deleted."), {
type,
name: item.name,
sprintf(__("Group '%{group_name}' is being deleted."), {
group_name: group.fullName,
}),
);
};
......
......@@ -16,7 +16,6 @@ export const formatGraphQLProjects = (projects, callback = () => {}) =>
const baseProject = {
...project,
id: getIdFromGraphQLId(id),
name: nameWithNamespace,
nameWithNamespace,
avatarLabel: nameWithNamespace,
mergeRequestsAccessLevel: mergeRequestsAccessLevel.stringValue,
......
......@@ -19,7 +19,7 @@ export const availableGraphQLProjectActions = ({ userPermissions }) => {
export const renderDeleteSuccessToast = (project) => {
toast(
sprintf(__("Project '%{project_name}' is being deleted."), {
project_name: project.name,
project_name: project.nameWithNamespace,
}),
);
};
......
import {
renderDeleteSuccessToast as renderDeleteSuccessToastCE,
deleteParams as deleteParamsCE,
} from '~/vue_shared/components/resource_lists/utils';
} from '~/vue_shared/components/groups_list/utils';
import toast from '~/vue_shared/plugins/global_toast';
import { sprintf, __ } from '~/locale';
// Exports override for EE
// eslint-disable-next-line import/export
export * from '~/vue_shared/components/resource_lists/utils';
export const renderRestoreSuccessToast = (item, type) => {
toast(
sprintf(__("%{type} '%{name}' has been successfully restored."), {
type,
name: item.name,
}),
);
};
export * from '~/vue_shared/components/groups_list/utils';
// Exports override for EE
// eslint-disable-next-line import/export
export const renderDeleteSuccessToast = (item, type) => {
export const renderDeleteSuccessToast = (item) => {
// If delayed deletion is disabled or the project/group is already marked for deletion, use the CE toast
if (!item.isAdjournedDeletionEnabled || item.markedForDeletionOn) {
renderDeleteSuccessToastCE(item, type);
renderDeleteSuccessToastCE(item);
return;
}
toast(
sprintf(__("%{type} '%{name}' will be deleted on %{date}."), {
type,
name: item.name,
sprintf(__("Group '%{group_name}' will be deleted on %{date}."), {
group_name: item.fullName,
date: item.permanentDeletionDate,
}),
);
......
......@@ -3,13 +3,13 @@ import { GlLoadingIcon } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { createAlert } from '~/alert';
import { restoreProject } from 'ee/rest_api';
import { renderRestoreSuccessToast } from 'ee/vue_shared/components/resource_lists/utils';
import ListActions from '~/vue_shared/components/list_actions/list_actions.vue';
import {
ACTION_EDIT,
ACTION_RESTORE,
ACTION_DELETE,
} from '~/vue_shared/components/list_actions/constants';
import { renderRestoreSuccessToast } from './utils';
export default {
name: 'ProjectListItemActionsEE',
......
......@@ -34,7 +34,7 @@ export const availableGraphQLProjectActions = ({ userPermissions, markedForDelet
export const renderRestoreSuccessToast = (project) => {
toast(
sprintf(__("Project '%{project_name}' has been successfully restored."), {
project_name: project.name,
project_name: project.nameWithNamespace,
}),
);
};
......@@ -52,7 +52,7 @@ export const renderDeleteSuccessToast = (project) => {
if (project.markedForDeletionOn) {
toast(
sprintf(__("Project '%{project_name}' is being deleted."), {
project_name: project.name,
project_name: project.nameWithNamespace,
}),
);
......@@ -63,7 +63,7 @@ export const renderDeleteSuccessToast = (project) => {
if (project.isAdjournedDeletionEnabled) {
toast(
sprintf(__("Project '%{project_name}' will be deleted on %{date}."), {
project_name: project.name,
project_name: project.nameWithNamespace,
date: project.permanentDeletionDate,
}),
);
......@@ -76,7 +76,7 @@ export const renderDeleteSuccessToast = (project) => {
// restored by an admin.
toast(
sprintf(__("Deleting project '%{project_name}'. All data will be removed on %{date}."), {
project_name: project.name,
project_name: project.nameWithNamespace,
date: project.permanentDeletionDate,
}),
);
......
import {
renderDeleteSuccessToast as renderDeleteSuccessToastCE,
deleteParams as deleteParamsCE,
} from '~/vue_shared/components/resource_lists/utils';
import {
deleteParams,
renderRestoreSuccessToast,
renderDeleteSuccessToast,
} from 'ee/vue_shared/components/resource_lists/utils';
} from '~/vue_shared/components/groups_list/utils';
import { deleteParams, renderDeleteSuccessToast } from 'ee/vue_shared/components/groups_list/utils';
import toast from '~/vue_shared/plugins/global_toast';
const MOCK_CE_PARAMS = { ceParam: true };
jest.mock('~/vue_shared/components/resource_lists/utils', () => ({
...jest.requireActual('~/vue_shared/components/resource_lists/utils'),
jest.mock('~/vue_shared/components/groups_list/utils', () => ({
...jest.requireActual('~/vue_shared/components/groups_list/utils'),
renderDeleteSuccessToast: jest.fn(),
deleteParams: jest.fn(() => MOCK_CE_PARAMS),
}));
jest.mock('~/vue_shared/plugins/global_toast');
const MOCK_PROJECT_NO_DELAY_DELETION = {
name: 'No Delay Project',
fullPath: 'path/to/project/1',
const MOCK_GROUP_NO_DELAY_DELETION = {
fullName: 'No Delay Group',
fullPath: 'path/to/group/1',
isAdjournedDeletionEnabled: false,
markedForDeletionOn: null,
permanentDeletionDate: null,
};
const MOCK_PROJECT_WITH_DELAY_DELETION = {
name: 'With Delay Project',
fullPath: 'path/to/project/2',
const MOCK_GROUP_WITH_DELAY_DELETION = {
fullName: 'With Delay Group',
fullPath: 'path/to/group/2',
isAdjournedDeletionEnabled: true,
markedForDeletionOn: null,
permanentDeletionDate: '2024-03-31',
};
const MOCK_PROJECT_PENDING_DELETION = {
name: 'Pending Deletion Project',
fullPath: 'path/to/project/3',
const MOCK_GROUP_PENDING_DELETION = {
fullName: 'Pending Deletion Group',
fullPath: 'path/to/group/3',
isAdjournedDeletionEnabled: true,
markedForDeletionOn: '2024-03-24',
permanentDeletionDate: '2024-03-31',
};
describe('renderRestoreSuccessToast', () => {
const MOCK_TYPE = 'Project';
it('calls toast correctly', () => {
renderRestoreSuccessToast(MOCK_PROJECT_PENDING_DELETION, MOCK_TYPE);
expect(toast).toHaveBeenCalledWith(
`${MOCK_TYPE} '${MOCK_PROJECT_PENDING_DELETION.name}' has been successfully restored.`,
);
});
});
describe('renderDeleteSuccessToast', () => {
const MOCK_TYPE = 'Project';
it('when delayed deletion is disabled, calls renderDeleteSuccessToastCE', () => {
renderDeleteSuccessToast(MOCK_PROJECT_NO_DELAY_DELETION, MOCK_TYPE);
renderDeleteSuccessToast(MOCK_GROUP_NO_DELAY_DELETION);
expect(renderDeleteSuccessToastCE).toHaveBeenCalledWith(
MOCK_PROJECT_NO_DELAY_DELETION,
MOCK_TYPE,
);
expect(renderDeleteSuccessToastCE).toHaveBeenCalledWith(MOCK_GROUP_NO_DELAY_DELETION);
expect(toast).not.toHaveBeenCalled();
});
it('when delayed deletion is enabled and project is not pending deletion, calls toast with pending deletion info', () => {
renderDeleteSuccessToast(MOCK_PROJECT_WITH_DELAY_DELETION, MOCK_TYPE);
renderDeleteSuccessToast(MOCK_GROUP_WITH_DELAY_DELETION);
expect(renderDeleteSuccessToastCE).not.toHaveBeenCalled();
expect(toast).toHaveBeenCalledWith(
`${MOCK_TYPE} '${MOCK_PROJECT_WITH_DELAY_DELETION.name}' will be deleted on ${MOCK_PROJECT_WITH_DELAY_DELETION.permanentDeletionDate}.`,
`Group '${MOCK_GROUP_WITH_DELAY_DELETION.fullName}' will be deleted on ${MOCK_GROUP_WITH_DELAY_DELETION.permanentDeletionDate}.`,
);
});
it('when delayed deletion is enabled and project is already pending deletion, calls renderDeleteSuccessToastCE', () => {
renderDeleteSuccessToast(MOCK_PROJECT_PENDING_DELETION, MOCK_TYPE);
renderDeleteSuccessToast(MOCK_GROUP_PENDING_DELETION);
expect(renderDeleteSuccessToastCE).toHaveBeenCalledWith(
MOCK_PROJECT_PENDING_DELETION,
MOCK_TYPE,
);
expect(renderDeleteSuccessToastCE).toHaveBeenCalledWith(MOCK_GROUP_PENDING_DELETION);
expect(toast).not.toHaveBeenCalled();
});
});
describe('deleteParams', () => {
it('when delayed deletion is disabled, returns deleteParamsCE', () => {
const res = deleteParams(MOCK_PROJECT_NO_DELAY_DELETION);
const res = deleteParams(MOCK_GROUP_NO_DELAY_DELETION);
expect(deleteParamsCE).toHaveBeenCalled();
expect(res).toStrictEqual(MOCK_CE_PARAMS);
});
it('when delayed deletion is enabled and project is not pending deletion, returns deleteParamsCE', () => {
const res = deleteParams(MOCK_PROJECT_WITH_DELAY_DELETION);
const res = deleteParams(MOCK_GROUP_WITH_DELAY_DELETION);
expect(deleteParamsCE).toHaveBeenCalled();
expect(res).toStrictEqual(MOCK_CE_PARAMS);
});
it('when delayed deletion is enabled and project is already pending deletion, returns permanent deletion params', () => {
const res = deleteParams(MOCK_PROJECT_PENDING_DELETION);
const res = deleteParams(MOCK_GROUP_PENDING_DELETION);
expect(deleteParamsCE).not.toHaveBeenCalled();
expect(res).toStrictEqual({
permanently_remove: true,
full_path: MOCK_PROJECT_PENDING_DELETION.fullPath,
full_path: MOCK_GROUP_PENDING_DELETION.fullPath,
});
});
});
......@@ -3,7 +3,7 @@ import { GlLoadingIcon } from '@gitlab/ui';
import projects from 'test_fixtures/api/users/projects/get.json';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { renderRestoreSuccessToast } from 'ee/vue_shared/components/resource_lists/utils';
import { renderRestoreSuccessToast } from 'ee/vue_shared/components/projects_list/utils';
import { restoreProject } from 'ee/rest_api';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import ListActions from '~/vue_shared/components/list_actions/list_actions.vue';
......@@ -15,8 +15,8 @@ import {
} from '~/vue_shared/components/list_actions/constants';
import { createAlert } from '~/alert';
jest.mock('ee/vue_shared/components/resource_lists/utils', () => ({
...jest.requireActual('ee/vue_shared/components/resource_lists/utils'),
jest.mock('ee/vue_shared/components/projects_list/utils', () => ({
...jest.requireActual('ee/vue_shared/components/projects_list/utils'),
renderRestoreSuccessToast: jest.fn(),
}));
jest.mock('~/alert');
......
......@@ -26,7 +26,7 @@ jest.mock('~/vue_shared/components/projects_list/utils', () => ({
}));
const MOCK_PERSONAL_PROJECT = {
name: 'No Delay Project',
nameWithNamespace: 'No Delay Project',
fullPath: 'path/to/project/1',
isAdjournedDeletionEnabled: false,
markedForDeletionOn: null,
......@@ -35,7 +35,7 @@ const MOCK_PERSONAL_PROJECT = {
};
const MOCK_PROJECT_NO_ADJOURNED_DELETION = {
name: 'No Delay Project',
nameWithNamespace: 'No Delay Project',
fullPath: 'path/to/project/1',
isAdjournedDeletionEnabled: false,
markedForDeletionOn: null,
......@@ -46,7 +46,7 @@ const MOCK_PROJECT_NO_ADJOURNED_DELETION = {
};
const MOCK_PROJECT_WITH_DELAY_DELETION = {
name: 'With Delay Project',
nameWithNamespace: 'With Delay Project',
fullPath: 'path/to/project/2',
isAdjournedDeletionEnabled: true,
markedForDeletionOn: null,
......@@ -57,7 +57,7 @@ const MOCK_PROJECT_WITH_DELAY_DELETION = {
};
const MOCK_PROJECT_PENDING_DELETION = {
name: 'Pending Deletion Project',
nameWithNamespace: 'Pending Deletion Project',
fullPath: 'path/to/project/3',
isAdjournedDeletionEnabled: true,
markedForDeletionOn: '2024-03-24',
......@@ -91,7 +91,7 @@ describe('renderRestoreSuccessToast', () => {
renderRestoreSuccessToast(MOCK_PROJECT_PENDING_DELETION);
expect(toast).toHaveBeenCalledWith(
`Project '${MOCK_PROJECT_PENDING_DELETION.name}' has been successfully restored.`,
`Project '${MOCK_PROJECT_PENDING_DELETION.nameWithNamespace}' has been successfully restored.`,
);
});
});
......@@ -108,7 +108,7 @@ describe('renderDeleteSuccessToast', () => {
it('renders toast explaining project will be delayed deleted', () => {
expect(toast).toHaveBeenCalledWith(
`Project '${MOCK_PROJECT_WITH_DELAY_DELETION.name}' will be deleted on ${MOCK_PROJECT_WITH_DELAY_DELETION.permanentDeletionDate}.`,
`Project '${MOCK_PROJECT_WITH_DELAY_DELETION.nameWithNamespace}' will be deleted on ${MOCK_PROJECT_WITH_DELAY_DELETION.permanentDeletionDate}.`,
);
});
});
......@@ -125,7 +125,7 @@ describe('renderDeleteSuccessToast', () => {
it('renders toast explaining project is deleted and when data will be removed', () => {
expect(toast).toHaveBeenCalledWith(
`Deleting project '${MOCK_PROJECT_NO_ADJOURNED_DELETION.name}'. All data will be removed on ${MOCK_PROJECT_NO_ADJOURNED_DELETION.permanentDeletionDate}.`,
`Deleting project '${MOCK_PROJECT_NO_ADJOURNED_DELETION.nameWithNamespace}'. All data will be removed on ${MOCK_PROJECT_NO_ADJOURNED_DELETION.permanentDeletionDate}.`,
);
});
});
......@@ -157,7 +157,7 @@ describe('renderDeleteSuccessToast', () => {
it('renders toast explaining project is being deleted', () => {
expect(toast).toHaveBeenCalledWith(
`Project '${MOCK_PROJECT_PENDING_DELETION.name}' is being deleted.`,
`Project '${MOCK_PROJECT_PENDING_DELETION.nameWithNamespace}' is being deleted.`,
);
});
});
......
......@@ -1552,15 +1552,6 @@ msgstr ""
msgid "%{total} warnings found: showing first %{warningsDisplayed}"
msgstr ""
 
msgid "%{type} '%{name}' has been successfully restored."
msgstr ""
msgid "%{type} '%{name}' is being deleted."
msgstr ""
msgid "%{type} '%{name}' will be deleted on %{date}."
msgstr ""
msgid "%{type} must be a %{help_link}"
msgstr ""
 
......@@ -28063,6 +28054,9 @@ msgstr ""
msgid "Group '%{group_name}' was successfully updated."
msgstr ""
 
msgid "Group '%{group_name}' will be deleted on %{date}."
msgstr ""
msgid "Group Git LFS status:"
msgstr ""
 
......@@ -12,7 +12,7 @@ import { formatGroups } from '~/organizations/shared/utils';
import {
renderDeleteSuccessToast,
deleteParams,
} from 'ee_else_ce/vue_shared/components/resource_lists/utils';
} from 'ee_else_ce/vue_shared/components/groups_list/utils';
import groupsQuery from '~/organizations/shared/graphql/queries/groups.query.graphql';
import GroupsList from '~/vue_shared/components/groups_list/groups_list.vue';
import { TIMESTAMP_TYPE_CREATED_AT } from '~/vue_shared/components/resource_lists/constants';
......@@ -46,8 +46,8 @@ const MOCK_DELETE_PARAMS = {
testParam: true,
};
jest.mock('ee_else_ce/vue_shared/components/resource_lists/utils', () => ({
...jest.requireActual('ee_else_ce/vue_shared/components/resource_lists/utils'),
jest.mock('ee_else_ce/vue_shared/components/groups_list/utils', () => ({
...jest.requireActual('ee_else_ce/vue_shared/components/groups_list/utils'),
renderDeleteSuccessToast: jest.fn(),
deleteParams: jest.fn(() => MOCK_DELETE_PARAMS),
}));
......
import organizationProjectsGraphQlResponse from 'test_fixtures/graphql/organizations/projects.query.graphql.json';
import {
deleteParams,
renderDeleteSuccessToast,
} from '~/vue_shared/components/resource_lists/utils';
import { formatGraphQLProjects } from '~/vue_shared/components/projects_list/formatter';
import organizationGroupsGraphQlResponse from 'test_fixtures/graphql/organizations/groups.query.graphql.json';
import { deleteParams, renderDeleteSuccessToast } from '~/vue_shared/components/groups_list/utils';
import { formatGroups } from '~/organizations/shared/utils';
import toast from '~/vue_shared/plugins/global_toast';
jest.mock('~/vue_shared/plugins/global_toast');
......@@ -11,19 +8,18 @@ jest.mock('~/vue_shared/plugins/global_toast');
const {
data: {
organization: {
projects: { nodes: projects },
groups: { nodes: groups },
},
},
} = organizationProjectsGraphQlResponse;
} = organizationGroupsGraphQlResponse;
describe('renderDeleteSuccessToast', () => {
const [MOCK_PROJECT] = formatGraphQLProjects(projects);
const MOCK_TYPE = 'Project';
const [MOCK_GROUP] = formatGroups(groups);
it('calls toast correctly', () => {
renderDeleteSuccessToast(MOCK_PROJECT, MOCK_TYPE);
renderDeleteSuccessToast(MOCK_GROUP);
expect(toast).toHaveBeenCalledWith(`${MOCK_TYPE} '${MOCK_PROJECT.name}' is being deleted.`);
expect(toast).toHaveBeenCalledWith(`Group '${MOCK_GROUP.fullName}' is being deleted.`);
});
});
......
......@@ -27,7 +27,6 @@ describe('formatGraphQLProjects', () => {
expect(firstFormattedProject).toMatchObject({
id: getIdFromGraphQLId(firstMockProject.id),
name: firstMockProject.nameWithNamespace,
nameWithNamespace: firstMockProject.nameWithNamespace,
avatarLabel: firstMockProject.nameWithNamespace,
mergeRequestsAccessLevel: firstMockProject.mergeRequestsAccessLevel.stringValue,
......
......@@ -38,7 +38,7 @@ describe('renderDeleteSuccessToast', () => {
it('calls toast correctly', () => {
renderDeleteSuccessToast(project);
expect(toast).toHaveBeenCalledWith(`Project '${project.name}' is being deleted.`);
expect(toast).toHaveBeenCalledWith(`Project '${project.nameWithNamespace}' is being deleted.`);
});
});
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册