@devtron-labs/devtron-fe-common-lib 0.0.10-beta-7 → 0.0.10-beta-9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Common/ImageTags.d.ts +1 -1
- package/dist/index.js +77 -61
- package/package.json +1 -1
- package/src/Common/ImageTags.tsx +97 -53
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ImageButtonType, ImageTaggingContainerType } from './Types';
|
|
3
|
-
export declare const ImageTagsContainer: ({ ciPipelineId, artifactId, imageComment, imageReleaseTags, appReleaseTagNames, tagsEditable, toggleCardMode, }: ImageTaggingContainerType) => JSX.Element;
|
|
3
|
+
export declare const ImageTagsContainer: ({ ciPipelineId, artifactId, imageComment, imageReleaseTags, appReleaseTagNames, setAppReleaseTagNames, tagsEditable, setTagsEditable, toggleCardMode, }: ImageTaggingContainerType) => JSX.Element;
|
|
4
4
|
export declare const ImageTagButton: ({ text, isSoftDeleted, isEditing, onSoftDeleteClick, onHardDeleteClick, tagId, softDeleteTags, isSuperAdmin, }: ImageButtonType) => JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -22763,7 +22763,7 @@ var SvgIcMinus = function SvgIcMinus(props) {
|
|
|
22763
22763
|
};
|
|
22764
22764
|
|
|
22765
22765
|
var ImageTagsContainer = function (_a) {
|
|
22766
|
-
var ciPipelineId = _a.ciPipelineId, artifactId = _a.artifactId, imageComment = _a.imageComment, imageReleaseTags = _a.imageReleaseTags, appReleaseTagNames = _a.appReleaseTagNames, tagsEditable = _a.tagsEditable, toggleCardMode = _a.toggleCardMode;
|
|
22766
|
+
var ciPipelineId = _a.ciPipelineId, artifactId = _a.artifactId, imageComment = _a.imageComment, imageReleaseTags = _a.imageReleaseTags, appReleaseTagNames = _a.appReleaseTagNames, setAppReleaseTagNames = _a.setAppReleaseTagNames, tagsEditable = _a.tagsEditable, setTagsEditable = _a.setTagsEditable, toggleCardMode = _a.toggleCardMode;
|
|
22767
22767
|
var _b = __read(React.useState(imageReleaseTags ? imageReleaseTags : []), 2), initialTags = _b[0], setInitialTags = _b[1];
|
|
22768
22768
|
var _c = __read(React.useState(imageComment ? imageComment.comment : ''), 2), initialDescription = _c[0], setInitialDescription = _c[1];
|
|
22769
22769
|
var _d = __read(React.useState(appReleaseTagNames ? appReleaseTagNames : []), 2), existingTags = _d[0], setExistingTags = _d[1];
|
|
@@ -22776,12 +22776,16 @@ var ImageTagsContainer = function (_a) {
|
|
|
22776
22776
|
var _l = __read(React.useState([]), 2), softDeleteTags = _l[0], setSoftDeleteTags = _l[1];
|
|
22777
22777
|
var _m = __read(React.useState([]), 2), hardDeleteTags = _m[0], setHardDeleteTags = _m[1];
|
|
22778
22778
|
var _o = __read(React.useState(false), 2), isSuperAdmin = _o[0], setSuperAdmin = _o[1];
|
|
22779
|
+
var _p = __read(React.useState(''), 2), descriptionValidationMessage = _p[0], setDescriptionValidationMessage = _p[1];
|
|
22779
22780
|
React.useEffect(function () {
|
|
22780
22781
|
initialise();
|
|
22781
22782
|
}, []);
|
|
22782
22783
|
React.useEffect(function () {
|
|
22783
22784
|
reInitState();
|
|
22784
|
-
}, [imageReleaseTags, imageComment,
|
|
22785
|
+
}, [imageReleaseTags, imageComment, tagsEditable]);
|
|
22786
|
+
React.useEffect(function () {
|
|
22787
|
+
setExistingTags(appReleaseTagNames ? appReleaseTagNames : []);
|
|
22788
|
+
}, [appReleaseTagNames]);
|
|
22785
22789
|
function initialise() {
|
|
22786
22790
|
var _a, _b;
|
|
22787
22791
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -22806,11 +22810,12 @@ var ImageTagsContainer = function (_a) {
|
|
|
22806
22810
|
});
|
|
22807
22811
|
}
|
|
22808
22812
|
var reInitState = function () {
|
|
22809
|
-
|
|
22810
|
-
|
|
22811
|
-
|
|
22812
|
-
|
|
22813
|
-
|
|
22813
|
+
if (isEditing === false) {
|
|
22814
|
+
setInitialTags(imageReleaseTags ? imageReleaseTags : []);
|
|
22815
|
+
setInitialDescription(imageComment ? imageComment.comment : '');
|
|
22816
|
+
setNewDescription(imageComment ? imageComment.comment : '');
|
|
22817
|
+
setDisplayedTags(imageReleaseTags ? imageReleaseTags : []);
|
|
22818
|
+
}
|
|
22814
22819
|
};
|
|
22815
22820
|
var CreatableComponents = React.useMemo(function () { return ({
|
|
22816
22821
|
DropdownIndicator: function () { return null; },
|
|
@@ -22824,7 +22829,11 @@ var ImageTagsContainer = function (_a) {
|
|
|
22824
22829
|
}
|
|
22825
22830
|
};
|
|
22826
22831
|
var handleDescriptionChange = function (e) {
|
|
22827
|
-
|
|
22832
|
+
var description = e.target.value;
|
|
22833
|
+
(description === null || description === void 0 ? void 0 : description.length) > 500
|
|
22834
|
+
? setDescriptionValidationMessage('comment length cannot exceed 500 characters')
|
|
22835
|
+
: setDescriptionValidationMessage('');
|
|
22836
|
+
setNewDescription(description);
|
|
22828
22837
|
};
|
|
22829
22838
|
var handleCancel = function () {
|
|
22830
22839
|
setDisplayedTags(initialTags);
|
|
@@ -22837,7 +22846,14 @@ var ImageTagsContainer = function (_a) {
|
|
|
22837
22846
|
setTagErrorMessage('');
|
|
22838
22847
|
};
|
|
22839
22848
|
var handleTagCreate = function (newValue) {
|
|
22840
|
-
var lowercaseValue = newValue.toLowerCase();
|
|
22849
|
+
var lowercaseValue = newValue.toLowerCase().trim();
|
|
22850
|
+
if (lowercaseValue.length == 0 ||
|
|
22851
|
+
lowercaseValue.length >= 128 ||
|
|
22852
|
+
lowercaseValue[0] == '.' ||
|
|
22853
|
+
lowercaseValue[0] == '-') {
|
|
22854
|
+
setTagErrorMessage('tag name cannot be empty or exceed 128 characters or cannot start with . or -');
|
|
22855
|
+
return;
|
|
22856
|
+
}
|
|
22841
22857
|
setTagErrorMessage('');
|
|
22842
22858
|
var isTagExistsInExistingTags = existingTags.includes(lowercaseValue);
|
|
22843
22859
|
var isTagExistsInDisplayedTags = false;
|
|
@@ -22845,8 +22861,8 @@ var ImageTagsContainer = function (_a) {
|
|
|
22845
22861
|
if (displayedTags[i].tagName.toLowerCase() === lowercaseValue)
|
|
22846
22862
|
isTagExistsInDisplayedTags = true;
|
|
22847
22863
|
}
|
|
22848
|
-
if (isTagExistsInExistingTags || isTagExistsInDisplayedTags) {
|
|
22849
|
-
setTagErrorMessage('This tag is already
|
|
22864
|
+
if (isTagExistsInExistingTags || isTagExistsInDisplayedTags || lowercaseValue === 'latest') {
|
|
22865
|
+
setTagErrorMessage('This tag is already being used in this application');
|
|
22850
22866
|
return;
|
|
22851
22867
|
}
|
|
22852
22868
|
var newTag = {
|
|
@@ -22892,58 +22908,57 @@ var ImageTagsContainer = function (_a) {
|
|
|
22892
22908
|
}
|
|
22893
22909
|
};
|
|
22894
22910
|
var handleSave = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
22895
|
-
var payload
|
|
22896
|
-
|
|
22897
|
-
|
|
22898
|
-
|
|
22899
|
-
|
|
22900
|
-
|
|
22901
|
-
|
|
22902
|
-
|
|
22903
|
-
|
|
22904
|
-
|
|
22905
|
-
|
|
22906
|
-
|
|
22907
|
-
|
|
22908
|
-
|
|
22909
|
-
|
|
22910
|
-
|
|
22911
|
-
|
|
22912
|
-
|
|
22913
|
-
|
|
22914
|
-
|
|
22915
|
-
|
|
22916
|
-
|
|
22917
|
-
|
|
22918
|
-
|
|
22919
|
-
|
|
22920
|
-
|
|
22921
|
-
|
|
22922
|
-
|
|
22923
|
-
|
|
22924
|
-
|
|
22925
|
-
|
|
22926
|
-
|
|
22927
|
-
|
|
22928
|
-
|
|
22929
|
-
|
|
22930
|
-
|
|
22931
|
-
|
|
22932
|
-
|
|
22933
|
-
|
|
22934
|
-
|
|
22935
|
-
|
|
22936
|
-
|
|
22937
|
-
|
|
22938
|
-
|
|
22939
|
-
}
|
|
22911
|
+
var payload;
|
|
22912
|
+
return __generator(this, function (_a) {
|
|
22913
|
+
payload = {
|
|
22914
|
+
createTags: createTags,
|
|
22915
|
+
softDeleteTags: softDeleteTags,
|
|
22916
|
+
imageComment: {
|
|
22917
|
+
id: 0,
|
|
22918
|
+
comment: newDescription.trim(),
|
|
22919
|
+
artifactId: 0,
|
|
22920
|
+
},
|
|
22921
|
+
hardDeleteTags: hardDeleteTags,
|
|
22922
|
+
};
|
|
22923
|
+
// set loading state true
|
|
22924
|
+
setImageTags(payload, ciPipelineId, artifactId)
|
|
22925
|
+
.then(function (res) {
|
|
22926
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
22927
|
+
var tags = (_b = (_a = res.result) === null || _a === void 0 ? void 0 : _a.imageReleaseTags) === null || _b === void 0 ? void 0 : _b.map(function (tag) { return ({
|
|
22928
|
+
id: tag.id,
|
|
22929
|
+
tagName: tag.tagName,
|
|
22930
|
+
deleted: tag.deleted,
|
|
22931
|
+
appId: 0,
|
|
22932
|
+
artifactId: 0,
|
|
22933
|
+
}); });
|
|
22934
|
+
if (setAppReleaseTagNames) {
|
|
22935
|
+
setAppReleaseTagNames((_c = res.result) === null || _c === void 0 ? void 0 : _c.appReleaseTags);
|
|
22936
|
+
}
|
|
22937
|
+
if (setTagsEditable) {
|
|
22938
|
+
setTagsEditable((_d = res.result) === null || _d === void 0 ? void 0 : _d.tagsEditable);
|
|
22939
|
+
}
|
|
22940
|
+
setInitialTags(tags);
|
|
22941
|
+
setInitialDescription((_f = (_e = res.result) === null || _e === void 0 ? void 0 : _e.imageComment) === null || _f === void 0 ? void 0 : _f.comment);
|
|
22942
|
+
setDisplayedTags(tags);
|
|
22943
|
+
setNewDescription((_h = (_g = res.result) === null || _g === void 0 ? void 0 : _g.imageComment) === null || _h === void 0 ? void 0 : _h.comment);
|
|
22944
|
+
setCreateTags([]);
|
|
22945
|
+
setSoftDeleteTags([]);
|
|
22946
|
+
setHardDeleteTags([]);
|
|
22947
|
+
handleEditClick();
|
|
22948
|
+
setShowTagsWarning(false);
|
|
22949
|
+
setTagErrorMessage('');
|
|
22950
|
+
})
|
|
22951
|
+
.catch(function (err) {
|
|
22952
|
+
showError(err);
|
|
22953
|
+
});
|
|
22954
|
+
return [2 /*return*/];
|
|
22940
22955
|
});
|
|
22941
22956
|
}); };
|
|
22942
22957
|
var renderInfoCard = function () {
|
|
22943
|
-
return (jsxRuntime.jsx(TippyCustomized, __assign({ theme: exports.TippyTheme.white, className: "w-300
|
|
22958
|
+
return (jsxRuntime.jsx(TippyCustomized, __assign({ theme: exports.TippyTheme.white, className: "w-300 fcv-5", placement: "right", Icon: SvgIcHelp, heading: "Release tags", showCloseButton: true, trigger: "click", interactive: true, documentationLinkText: "View Documentation", additionalContent: getBuildContextAdditionalContent() }, { children: jsxRuntime.jsx("div", __assign({ className: "icon-dim-16 fcn-5 ml-8 cursor" }, { children: jsxRuntime.jsx(SvgIcHelpOutline, {}) })) })));
|
|
22944
22959
|
};
|
|
22945
22960
|
var getBuildContextAdditionalContent = function () {
|
|
22946
|
-
return (jsxRuntime.
|
|
22961
|
+
return (jsxRuntime.jsxs("div", __assign({ className: "h-250 fs-13 dc__overflow-scroll p-12" }, { children: [jsxRuntime.jsx("div", { children: "Release tags allow you to tag container images with readable and relatable tags eg. v1.0." }), jsxRuntime.jsxs("ul", __assign({ className: 'pl-20 mt-8' }, { children: [jsxRuntime.jsx("li", { children: "A release tag can only be added if a workflow has CD pipelines deploying to Production environments." }), jsxRuntime.jsx("li", { children: "Multiple tags can be added to an image." }), jsxRuntime.jsx("li", { children: "Multiple images in an application cannot have the same tag." }), jsxRuntime.jsx("li", { children: "Tags cannot be deleted once saved. Although, you can soft delete a tag if an unwanted tag has been added." })] }))] })));
|
|
22947
22962
|
};
|
|
22948
22963
|
var creatableRef = React.useRef(null);
|
|
22949
22964
|
if (newDescription === '' && displayedTags.length === 0 && !isEditing) {
|
|
@@ -22955,7 +22970,7 @@ var ImageTagsContainer = function (_a) {
|
|
|
22955
22970
|
}, onHardDeleteClick: function (e) {
|
|
22956
22971
|
stopPropagation(e);
|
|
22957
22972
|
handleTagHardDelete(index);
|
|
22958
|
-
}, tagId: tag.id, softDeleteTags: softDeleteTags, isSuperAdmin: isSuperAdmin }, tag.id)); }) })), showTagsWarning && (jsxRuntime.jsxs("div", __assign({ className: "cn-7 mb-8 flex left" }, { children: [jsxRuntime.jsx(SvgIcInfoFilled, { className: "form__icon--info icon-dim-16 mr-2" }), "Tags cannot be edited/removed later"] }))), jsxRuntime.jsx("div", __assign({ className: "cn-7 mt-12" }, { children: "Comment" })), jsxRuntime.jsx("div", __assign({ className: "flex left flex-wrap dc__gap-8 w-100 mt-6 mb-12", "data-testid": "add-image-comment-text-area" }, { children: jsxRuntime.jsx("textarea", { value: newDescription, onChange: handleDescriptionChange, className: "flex left flex-wrap dc__gap-8 dc__description-textarea", style: { height: '90px !important' } }) })), jsxRuntime.jsxs("div", __assign({ className: "w-100 flex right" }, { children: [jsxRuntime.jsx("button", __assign({ className: "cta flex cancel h-32 lh-32-imp", type: "button", onClick: function (e) {
|
|
22973
|
+
}, tagId: tag.id, softDeleteTags: softDeleteTags, isSuperAdmin: isSuperAdmin }, tag.id)); }) })), showTagsWarning && (jsxRuntime.jsxs("div", __assign({ className: "cn-7 mb-8 flex left" }, { children: [jsxRuntime.jsx(SvgIcInfoFilled, { className: "form__icon--info icon-dim-16 mr-2" }), "Tags cannot be edited/removed later"] }))), jsxRuntime.jsx("div", __assign({ className: "cn-7 mt-12" }, { children: "Comment" })), jsxRuntime.jsx("div", __assign({ className: "flex left flex-wrap dc__gap-8 w-100 mt-6 mb-12", "data-testid": "add-image-comment-text-area" }, { children: jsxRuntime.jsx("textarea", { value: newDescription, onChange: handleDescriptionChange, className: "flex left flex-wrap dc__gap-8 dc__description-textarea", style: { height: '90px !important' } }) })), descriptionValidationMessage !== '' && (jsxRuntime.jsxs("div", __assign({ className: "flex left" }, { children: [jsxRuntime.jsx(SvgIcWarning, { className: "form__icon form__icon--error" }), jsxRuntime.jsx("div", __assign({ className: "form__error" }, { children: descriptionValidationMessage }))] }))), jsxRuntime.jsxs("div", __assign({ className: "w-100 flex right mt-12" }, { children: [jsxRuntime.jsx("button", __assign({ className: "cta flex cancel h-32 lh-32-imp", type: "button", onClick: function (e) {
|
|
22959
22974
|
stopPropagation(e);
|
|
22960
22975
|
handleCancel();
|
|
22961
22976
|
} }, { children: "Cancel" })), jsxRuntime.jsx("button", __assign({ className: "cta flex h-32 lh-32-imp ml-12", "data-testid": "save-tags-button", type: "button", onClick: function (e) {
|
|
@@ -22988,11 +23003,12 @@ var ImageTagButton = function (_a) {
|
|
|
22988
23003
|
};
|
|
22989
23004
|
var isInSoftDeleteTags = isSoftDeleted && softDeleteTags.some(function (tag) { return tag.tagName === text; });
|
|
22990
23005
|
var canTagBeHardDelete = tagId === 0 || isSuperAdmin;
|
|
22991
|
-
return (jsxRuntime.jsx("div", __assign({ className: "br-4 en-2 bw-1 dc__w-fit-content dc__word-wrap-anywhere mr-8 bcn-0 flex h-24 ".concat(isSoftDeleted ? 'cy-7 bcy-1 dc__strike-through ey-2' : ''), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave }, { children: jsxRuntime.jsxs("div", __assign({ className: "flex pt-2 pl-8 pr-8 pb-2" }, { children: [isHovered && isEditing && (isInSoftDeleteTags || (tagId !== 0 && !isSoftDeleted)) && (jsxRuntime.jsx(IconComponent, { className: "icon-dim-12 mr-4 cursor ".concat(isSoftDeleted ? 'scn-6' : 'fcn-6'), "data-testid": "".concat(text, "-tag-soft-delete"), onClick: onSoftDeleteClick })), text, isHovered && isEditing && canTagBeHardDelete && (jsxRuntime.jsx(SvgIcCross, { className: "icon-dim-12 ml-4 fcn-6 cn-5 cursor", "data-testid": "".concat(text, "-tag-hard-delete"), onClick: onHardDeleteClick }))] })) })));
|
|
23006
|
+
return (jsxRuntime.jsx("div", __assign({ className: "br-4 en-2 bw-1 dc__w-fit-content dc__word-wrap-anywhere mr-8 bcn-0 flex h-24 ".concat(isSoftDeleted ? 'cy-7 bcy-1 dc__strike-through ey-2' : ''), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave }, { children: jsxRuntime.jsxs("div", __assign({ className: "flex pt-2 pl-8 pr-8 pb-2" }, { children: [isHovered && isEditing && (isInSoftDeleteTags || (tagId !== 0 && !isSoftDeleted)) && (jsxRuntime.jsx(Tippy, __assign({ className: "default-tt", arrow: true, placement: "top", content: isInSoftDeleteTags ? 'Restore tag' : 'Soft delete tag' }, { children: jsxRuntime.jsx(IconComponent, { className: "icon-dim-12 mr-4 cursor ".concat(isSoftDeleted ? 'scn-6' : 'fcn-6'), "data-testid": "".concat(text, "-tag-soft-delete"), onClick: onSoftDeleteClick }) }))), text, isHovered && isEditing && canTagBeHardDelete && (jsxRuntime.jsx(Tippy, __assign({ className: "default-tt", arrow: true, placement: "top", content: "Remove tag" }, { children: jsxRuntime.jsx(SvgIcCross, { className: "icon-dim-12 ml-4 fcn-6 cn-5 cursor", "data-testid": "".concat(text, "-tag-hard-delete"), onClick: onHardDeleteClick }) })))] })) })));
|
|
22992
23007
|
};
|
|
22993
23008
|
var AddImageButton = function (_a) {
|
|
22994
23009
|
var handleEditClick = _a.handleEditClick;
|
|
22995
|
-
var handleClick = function () {
|
|
23010
|
+
var handleClick = function (e) {
|
|
23011
|
+
stopPropagation(e);
|
|
22996
23012
|
handleEditClick();
|
|
22997
23013
|
};
|
|
22998
23014
|
return (jsxRuntime.jsx("div", __assign({ className: "add-tag-button flex pt-12 pr-12", "data-testid": "add-tags-button", onClick: handleClick }, { children: jsxRuntime.jsxs("div", __assign({ className: "lh-16 flex" }, { children: [jsxRuntime.jsx(SvgIcAdd, { className: "icon-dim-16 cn-6" }), jsxRuntime.jsx("span", __assign({ className: "cn-7" }, { children: "Add tags/comment" }))] })) })));
|
package/package.json
CHANGED
package/src/Common/ImageTags.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import { ImageButtonType, ImageTaggingContainerType, ReleaseTag, TippyTheme } fr
|
|
|
15
15
|
import { showError, stopPropagation } from './Helper'
|
|
16
16
|
import { TippyCustomized } from './TippyCustomized'
|
|
17
17
|
import { setImageTags, getUserRole } from './Common.service'
|
|
18
|
+
import Tippy from '@tippyjs/react'
|
|
18
19
|
|
|
19
20
|
export const ImageTagsContainer = ({
|
|
20
21
|
ciPipelineId,
|
|
@@ -22,7 +23,9 @@ export const ImageTagsContainer = ({
|
|
|
22
23
|
imageComment,
|
|
23
24
|
imageReleaseTags,
|
|
24
25
|
appReleaseTagNames,
|
|
26
|
+
setAppReleaseTagNames,
|
|
25
27
|
tagsEditable,
|
|
28
|
+
setTagsEditable,
|
|
26
29
|
toggleCardMode,
|
|
27
30
|
}: ImageTaggingContainerType) => {
|
|
28
31
|
const [initialTags, setInitialTags] = useState<ReleaseTag[]>(imageReleaseTags ? imageReleaseTags : [])
|
|
@@ -37,6 +40,7 @@ export const ImageTagsContainer = ({
|
|
|
37
40
|
const [softDeleteTags, setSoftDeleteTags] = useState<ReleaseTag[]>([])
|
|
38
41
|
const [hardDeleteTags, setHardDeleteTags] = useState<ReleaseTag[]>([])
|
|
39
42
|
const [isSuperAdmin, setSuperAdmin] = useState<boolean>(false)
|
|
43
|
+
const [descriptionValidationMessage, setDescriptionValidationMessage] = useState<string>('')
|
|
40
44
|
|
|
41
45
|
useEffect(() => {
|
|
42
46
|
initialise()
|
|
@@ -44,7 +48,11 @@ export const ImageTagsContainer = ({
|
|
|
44
48
|
|
|
45
49
|
useEffect(() => {
|
|
46
50
|
reInitState()
|
|
47
|
-
}, [imageReleaseTags, imageComment,
|
|
51
|
+
}, [imageReleaseTags, imageComment, tagsEditable])
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
setExistingTags(appReleaseTagNames ? appReleaseTagNames : [])
|
|
55
|
+
}, [appReleaseTagNames])
|
|
48
56
|
|
|
49
57
|
async function initialise() {
|
|
50
58
|
try {
|
|
@@ -58,11 +66,12 @@ export const ImageTagsContainer = ({
|
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
const reInitState = () => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
if (isEditing === false) {
|
|
70
|
+
setInitialTags(imageReleaseTags ? imageReleaseTags : [])
|
|
71
|
+
setInitialDescription(imageComment ? imageComment.comment : '')
|
|
72
|
+
setNewDescription(imageComment ? imageComment.comment : '')
|
|
73
|
+
setDisplayedTags(imageReleaseTags ? imageReleaseTags : [])
|
|
74
|
+
}
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
const CreatableComponents = useMemo(
|
|
@@ -82,7 +91,11 @@ export const ImageTagsContainer = ({
|
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
const handleDescriptionChange = (e) => {
|
|
85
|
-
|
|
94
|
+
const description = e.target.value
|
|
95
|
+
description?.length > 500
|
|
96
|
+
? setDescriptionValidationMessage('comment length cannot exceed 500 characters')
|
|
97
|
+
: setDescriptionValidationMessage('')
|
|
98
|
+
setNewDescription(description)
|
|
86
99
|
}
|
|
87
100
|
|
|
88
101
|
const handleCancel = () => {
|
|
@@ -97,15 +110,26 @@ export const ImageTagsContainer = ({
|
|
|
97
110
|
}
|
|
98
111
|
|
|
99
112
|
const handleTagCreate = (newValue) => {
|
|
100
|
-
const lowercaseValue = newValue.toLowerCase()
|
|
113
|
+
const lowercaseValue = newValue.toLowerCase().trim()
|
|
114
|
+
if (
|
|
115
|
+
lowercaseValue.length == 0 ||
|
|
116
|
+
lowercaseValue.length >= 128 ||
|
|
117
|
+
lowercaseValue[0] == '.' ||
|
|
118
|
+
lowercaseValue[0] == '-'
|
|
119
|
+
) {
|
|
120
|
+
setTagErrorMessage('tag name cannot be empty or exceed 128 characters or cannot start with . or -')
|
|
121
|
+
return
|
|
122
|
+
}
|
|
101
123
|
setTagErrorMessage('')
|
|
102
124
|
const isTagExistsInExistingTags = existingTags.includes(lowercaseValue)
|
|
103
125
|
let isTagExistsInDisplayedTags = false
|
|
104
126
|
for (let i = 0; i < displayedTags?.length; i++) {
|
|
105
127
|
if (displayedTags[i].tagName.toLowerCase() === lowercaseValue) isTagExistsInDisplayedTags = true
|
|
106
128
|
}
|
|
107
|
-
if (isTagExistsInExistingTags || isTagExistsInDisplayedTags) {
|
|
108
|
-
setTagErrorMessage(
|
|
129
|
+
if (isTagExistsInExistingTags || isTagExistsInDisplayedTags || lowercaseValue === 'latest') {
|
|
130
|
+
setTagErrorMessage(
|
|
131
|
+
'This tag is already being used in this application',
|
|
132
|
+
)
|
|
109
133
|
return
|
|
110
134
|
}
|
|
111
135
|
const newTag: ReleaseTag = {
|
|
@@ -167,40 +191,46 @@ export const ImageTagsContainer = ({
|
|
|
167
191
|
hardDeleteTags: hardDeleteTags,
|
|
168
192
|
}
|
|
169
193
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
194
|
+
// set loading state true
|
|
195
|
+
setImageTags(payload, ciPipelineId, artifactId)
|
|
196
|
+
.then((res) => {
|
|
197
|
+
const tags = res.result?.imageReleaseTags?.map((tag) => ({
|
|
198
|
+
id: tag.id,
|
|
199
|
+
tagName: tag.tagName,
|
|
200
|
+
deleted: tag.deleted,
|
|
201
|
+
appId: 0,
|
|
202
|
+
artifactId: 0,
|
|
203
|
+
}))
|
|
204
|
+
if (setAppReleaseTagNames) {
|
|
205
|
+
setAppReleaseTagNames(res.result?.appReleaseTags)
|
|
206
|
+
}
|
|
207
|
+
if (setTagsEditable) {
|
|
208
|
+
setTagsEditable(res.result?.tagsEditable)
|
|
209
|
+
}
|
|
210
|
+
setInitialTags(tags)
|
|
211
|
+
setInitialDescription(res.result?.imageComment?.comment)
|
|
212
|
+
setDisplayedTags(tags)
|
|
213
|
+
setNewDescription(res.result?.imageComment?.comment)
|
|
214
|
+
setCreateTags([])
|
|
215
|
+
setSoftDeleteTags([])
|
|
216
|
+
setHardDeleteTags([])
|
|
217
|
+
handleEditClick()
|
|
218
|
+
setShowTagsWarning(false)
|
|
219
|
+
setTagErrorMessage('')
|
|
220
|
+
})
|
|
221
|
+
.catch((err) => {
|
|
222
|
+
showError(err)
|
|
223
|
+
})
|
|
193
224
|
}
|
|
194
225
|
|
|
195
226
|
const renderInfoCard = (): JSX.Element => {
|
|
196
227
|
return (
|
|
197
228
|
<TippyCustomized
|
|
198
229
|
theme={TippyTheme.white}
|
|
199
|
-
className="w-300
|
|
230
|
+
className="w-300 fcv-5"
|
|
200
231
|
placement="right"
|
|
201
232
|
Icon={QuestionFilled}
|
|
202
233
|
heading="Release tags"
|
|
203
|
-
infoText="Release tags allow you to tag container images with readable and relatable tags eg. v1.0."
|
|
204
234
|
showCloseButton={true}
|
|
205
235
|
trigger="click"
|
|
206
236
|
interactive={true}
|
|
@@ -216,8 +246,9 @@ export const ImageTagsContainer = ({
|
|
|
216
246
|
|
|
217
247
|
const getBuildContextAdditionalContent = () => {
|
|
218
248
|
return (
|
|
219
|
-
<div className="
|
|
220
|
-
<
|
|
249
|
+
<div className="h-250 fs-13 dc__overflow-scroll p-12">
|
|
250
|
+
<div>Release tags allow you to tag container images with readable and relatable tags eg. v1.0.</div>
|
|
251
|
+
<ul className='pl-20 mt-8'>
|
|
221
252
|
<li>
|
|
222
253
|
A release tag can only be added if a workflow has CD pipelines deploying to Production
|
|
223
254
|
environments.
|
|
@@ -296,10 +327,7 @@ export const ImageTagsContainer = ({
|
|
|
296
327
|
</div>
|
|
297
328
|
)}
|
|
298
329
|
<div className="cn-7 mt-12">Comment</div>
|
|
299
|
-
<div
|
|
300
|
-
className="flex left flex-wrap dc__gap-8 w-100 mt-6 mb-12"
|
|
301
|
-
data-testid="add-image-comment-text-area"
|
|
302
|
-
>
|
|
330
|
+
<div className="flex left flex-wrap dc__gap-8 w-100 mt-6 mb-12" data-testid="add-image-comment-text-area">
|
|
303
331
|
<textarea
|
|
304
332
|
value={newDescription}
|
|
305
333
|
onChange={handleDescriptionChange}
|
|
@@ -307,7 +335,13 @@ export const ImageTagsContainer = ({
|
|
|
307
335
|
style={{ height: '90px !important' }}
|
|
308
336
|
/>
|
|
309
337
|
</div>
|
|
310
|
-
|
|
338
|
+
{descriptionValidationMessage !== '' && (
|
|
339
|
+
<div className="flex left">
|
|
340
|
+
<Error className="form__icon form__icon--error" />
|
|
341
|
+
<div className="form__error">{descriptionValidationMessage}</div>
|
|
342
|
+
</div>
|
|
343
|
+
)}
|
|
344
|
+
<div className="w-100 flex right mt-12">
|
|
311
345
|
<button
|
|
312
346
|
className="cta flex cancel h-32 lh-32-imp"
|
|
313
347
|
type="button"
|
|
@@ -417,19 +451,28 @@ export const ImageTagButton = ({
|
|
|
417
451
|
>
|
|
418
452
|
<div className="flex pt-2 pl-8 pr-8 pb-2">
|
|
419
453
|
{isHovered && isEditing && (isInSoftDeleteTags || (tagId !== 0 && !isSoftDeleted)) && (
|
|
420
|
-
<
|
|
421
|
-
className=
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
454
|
+
<Tippy
|
|
455
|
+
className="default-tt"
|
|
456
|
+
arrow={true}
|
|
457
|
+
placement="top"
|
|
458
|
+
content={isInSoftDeleteTags ? 'Restore tag' : 'Soft delete tag'}
|
|
459
|
+
>
|
|
460
|
+
<IconComponent
|
|
461
|
+
className={`icon-dim-12 mr-4 cursor ${isSoftDeleted ? 'scn-6' : 'fcn-6'}`}
|
|
462
|
+
data-testid={`${text}-tag-soft-delete`}
|
|
463
|
+
onClick={onSoftDeleteClick}
|
|
464
|
+
/>
|
|
465
|
+
</Tippy>
|
|
425
466
|
)}
|
|
426
467
|
{text}
|
|
427
468
|
{isHovered && isEditing && canTagBeHardDelete && (
|
|
428
|
-
<
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
469
|
+
<Tippy className="default-tt" arrow={true} placement="top" content="Remove tag">
|
|
470
|
+
<Close
|
|
471
|
+
className="icon-dim-12 ml-4 fcn-6 cn-5 cursor"
|
|
472
|
+
data-testid={`${text}-tag-hard-delete`}
|
|
473
|
+
onClick={onHardDeleteClick}
|
|
474
|
+
/>
|
|
475
|
+
</Tippy>
|
|
433
476
|
)}
|
|
434
477
|
</div>
|
|
435
478
|
</div>
|
|
@@ -437,7 +480,8 @@ export const ImageTagButton = ({
|
|
|
437
480
|
}
|
|
438
481
|
|
|
439
482
|
const AddImageButton = ({ handleEditClick }) => {
|
|
440
|
-
const handleClick = () => {
|
|
483
|
+
const handleClick = (e) => {
|
|
484
|
+
stopPropagation(e)
|
|
441
485
|
handleEditClick()
|
|
442
486
|
}
|
|
443
487
|
|