From f0fe33388c7c6dac93febc3661d16c536932fda8 Mon Sep 17 00:00:00 2001 From: Aleksandr Gorodetskii Date: Wed, 30 Aug 2023 11:39:44 +0300 Subject: [PATCH 1/2] GUI redundant requests fixes (#3347) * GUI redundant reguests fix: Tool -load * GUI redundant reguests fix: Tool -info (versions) * GUI redundant reguests fix: Tool -settings (version settings) * GUI redundant reguests fix: Tool -policy (scan policy) --- client/src/components/tools/Tool.js | 395 ++++++++++++++++++---------- 1 file changed, 252 insertions(+), 143 deletions(-) diff --git a/client/src/components/tools/Tool.js b/client/src/components/tools/Tool.js index ea0f292204..436640c560 100644 --- a/client/src/components/tools/Tool.js +++ b/client/src/components/tools/Tool.js @@ -99,18 +99,19 @@ const DEFAULT_FILE_SIZE_KB = 50; @HiddenObjects.injectToolsFilters @HiddenObjects.checkTools(props => props?.params?.id) @inject('awsRegions', 'dockerRegistries', 'preferences', 'usersInfo') -@inject(({allowedInstanceTypes, dockerRegistries, authenticatedUserInfo, preferences}, {params}) => { +@inject(({ + allowedInstanceTypes, + dockerRegistries, + authenticatedUserInfo, + preferences +}, {params}) => { return { allowedInstanceTypesCache: allowedInstanceTypes, toolId: params.id, - tool: new LoadTool(params.id), - versions: new LoadToolAttributes(params.id), section: params.section.toLowerCase(), preferences, docker: dockerRegistries, - scanPolicy: new LoadToolScanPolicy(), - authenticatedUserInfo, - versionSettings: new LoadToolVersionSettings(params.id) + authenticatedUserInfo }; }) @withCurrentUserAttributes() @@ -132,6 +133,46 @@ export default class Tool extends localization.LocalizedReactComponent { }; @observable defaultVersionSettings; + @observable toolPending = false; + @observable toolRequest; + @observable versionsPending = false; + @observable versionsRequest; + @observable versionSettingsPending = false; + @observable versionSettingsRequest; + @observable scanPolicyPending = false; + @observable scanPolicyRequest; + + @computed + get tool () { + if (this.toolRequest && this.toolRequest.loaded) { + return this.toolRequest.value; + } + return null; + } + + @computed + get versions () { + if (this.versionsRequest && this.versionsRequest.loaded) { + return this.versionsRequest.value?.versions; + } + return null; + } + + @computed + get versionSettings () { + if (this.versionSettingsRequest && this.versionSettingsRequest.loaded) { + return this.versionSettingsRequest.value; + } + return null; + } + + @computed + get scanPolicy () { + if (this.scanPolicyRequest && this.scanPolicyRequest.loaded) { + return this.scanPolicyRequest.value; + } + return null; + } @computed get awsRegions () { @@ -201,21 +242,20 @@ export default class Tool extends localization.LocalizedReactComponent { @computed get dockerRegistry () { - if (this.registries.length > 0 && this.props.tool.loaded) { + if (this.registries.length > 0 && this.tool) { return this.registries - .find(r => r.id === this.props.tool.value.registryId); + .find(r => r.id === this.tool.registryId); } return null; } @computed get toolGroup () { - const {tool} = this.props; const {dockerRegistry} = this; - if (dockerRegistry && tool && tool.loaded) { + if (dockerRegistry && this.tool) { const { toolGroupId - } = tool.value; + } = this.tool; const { groups = [] } = dockerRegistry; @@ -226,24 +266,24 @@ export default class Tool extends localization.LocalizedReactComponent { @computed get toolImage () { - if (this.props.tool.loaded) { - return `${this.props.tool.value.registry}/${this.props.tool.value.image}`; + if (this.tool) { + return `${this.tool.registry}/${this.tool.image}`; } return null; } @computed get link () { - if (this.props.tool.loaded) { - return !!this.props.tool.value.link; + if (this.tool) { + return !!this.tool.link; } return false; } @computed get hasWritableToolGroups () { - if (this.registries.length > 0 && this.props.tool.loaded) { - const toolGroupId = +(this.props.tool.value.toolGroupId); + if (this.registries.length > 0 && this.tool) { + const toolGroupId = +(this.tool.toolGroupId); for (let r = 0; r < this.registries.length; r++) { const groups = this.registries[r].groups || []; if (groups.filter(g => +g.id !== toolGroupId && roleModel.writeAllowed(g)).length > 0) { @@ -265,26 +305,81 @@ export default class Tool extends localization.LocalizedReactComponent { return []; } - fetchVersions = async () => { - await this.props.versions.fetch(); + + loadTool = async (toolId) => { + if (!toolId) { + return; + } + this.toolRequest = new LoadTool(toolId); + this.toolPending = true; + await this.toolRequest.fetch(); + if (this.toolRequest.error) { + message.error(this.toolRequest.error, 5); + } + this.toolPending = false; + }; + + loadVersions = async (toolId) => { + if (!toolId) { + return; + } + this.versionsRequest = new LoadToolAttributes(toolId); + this.versionsPending = true; + await this.versionsRequest.fetch(); + if (this.versionsRequest.error) { + message.error(this.versionsRequest.error, 5); + } + this.versionsPending = false; + }; + + loadVersionSettings = async (toolId) => { + if (!toolId) { + return; + } + this.versionSettingsRequest = new LoadToolVersionSettings(toolId); + this.versionSettingsPending = true; + await this.versionSettingsRequest.fetch(); + if (this.versionSettingsRequest.error) { + message.error(this.versionSettingsRequest.error, 5); + } + this.versionSettingsPending = false; + }; + + loadScanPolicy = async () => { + this.scanPolicyRequest = new LoadToolScanPolicy(); + this.scanPolicyPending = true; + await this.scanPolicyRequest.fetch(); + if (this.scanPolicyRequest.error) { + message.error(this.scanPolicyRequest.error, 5); + } + this.scanPolicyPending = false; + }; + + loadToolInfo = async () => { + await Promise.all([ + this.loadTool(this.props.toolId), + this.loadVersions(this.props.toolId), + this.loadVersionSettings(this.props.toolId), + this.loadScanPolicy() + ]); }; updateTool = async (values, configuration, allowCommit) => { const hide = message.loading('Updating settings...', 0); const request = new ToolUpdate(); const tool = { - image: this.props.tool.value.image, - registry: this.props.tool.value.registry, - registryId: this.props.tool.value.registryId, - description: this.props.tool.value.description, - shortDescription: this.props.tool.value.shortDescription, + image: this.tool.image, + registry: this.tool.registry, + registryId: this.tool.registryId, + description: this.tool.description, + shortDescription: this.tool.shortDescription, ...values }; await request.send(tool); let updateToolVersionParametersRequest; if (this.defaultTag && configuration) { updateToolVersionParametersRequest = new UpdateToolVersionSettings( - this.props.tool.value.id, + this.tool.id, this.defaultTag, allowCommit ); @@ -297,12 +392,15 @@ export default class Tool extends localization.LocalizedReactComponent { hide(); if (request.error) { message.error(request.error, 5); - } else if (updateToolVersionParametersRequest && updateToolVersionParametersRequest.error) { + } else if ( + updateToolVersionParametersRequest && + updateToolVersionParametersRequest.error + ) { message.error(updateToolVersionParametersRequest.error, 5); } else { - await this.props.tool.fetch(); + await this.loadTool(this.tool.id); this.defaultVersionSettings && await this.defaultVersionSettings.fetch(); - this.props.versionSettings && await this.props.versionSettings.fetch(); + this.loadVersionSettings(this.props.toolId); } }; @@ -344,7 +442,7 @@ export default class Tool extends localization.LocalizedReactComponent { if (!version) { this.navigateBack(); } else { - await this.fetchVersions(); + await this.loadVersions(this.props.toolId); } } }; @@ -358,14 +456,14 @@ export default class Tool extends localization.LocalizedReactComponent { toggleEditDescriptionMode = (mode) => { this.setState({ editDescriptionMode: mode, - description: mode ? this.props.tool.value.description : null + description: mode ? this.tool.description : null }); }; toggleEditShortDescriptionMode = (mode) => { this.setState({ editShortDescriptionMode: mode, - shortDescription: mode ? this.props.tool.value.shortDescription : null + shortDescription: mode ? this.tool.shortDescription : null }); }; @@ -373,28 +471,29 @@ export default class Tool extends localization.LocalizedReactComponent { const hide = message.loading('Updating description...', 0); const request = new ToolUpdate(); const tool = { - image: this.props.tool.value.image, - registry: this.props.tool.value.registry, - registryId: this.props.tool.value.registryId, - disk: this.props.tool.value.disk, - labels: - this.props.tool.value.labels ? (this.props.tool.value.labels || []).map(l => l) : undefined, - endpoints: - this.props.tool.value.endpoints - ? (this.props.tool.value.endpoints || []).map(l => l) - : undefined, - instanceType: this.props.tool.value.instanceType, - defaultCommand: this.props.tool.value.defaultCommand, - description: isShortDescription ? this.props.tool.value.description : this.state.description, - shortDescription: - isShortDescription ? this.state.shortDescription : this.props.tool.value.shortDescription + image: this.tool.image, + registry: this.tool.registry, + registryId: this.tool.registryId, + disk: this.tool.disk, + labels: this.tool.labels + ? (this.tool.labels || []).map(l => l) + : undefined, + endpoints: this.tool.endpoints + ? (this.tool.endpoints || []).map(l => l) + : undefined, + instanceType: this.tool.instanceType, + defaultCommand: this.tool.defaultCommand, + description: isShortDescription ? this.tool.description : this.state.description, + shortDescription: isShortDescription + ? this.state.shortDescription + : this.tool.shortDescription }; await request.send(tool); hide(); if (request.error) { message.error(request.error, 5); } else { - await this.props.tool.fetch(); + await this.loadTool(tool.id); if (isShortDescription) { this.toggleEditShortDescriptionMode(false); } else { @@ -408,18 +507,18 @@ export default class Tool extends localization.LocalizedReactComponent { }; renderToolImageControl = () => { - if (!this.props.tool.loaded) { + if (!this.tool) { return null; } let image; - if (this.props.tool.value.iconId) { + if (this.tool.iconId) { image = ( + src={ToolImage.url(this.tool.id, this.tool.iconId)} /> ); } else { image = ( @@ -442,7 +541,7 @@ export default class Tool extends localization.LocalizedReactComponent { } const hide = message.loading('Uploading new image...', 0); const refresh = () => { - this.props.tool.fetch(); + this.loadTool(this.tool.id); }; const formData = new FormData(); formData.append('file', file); @@ -466,7 +565,7 @@ export default class Tool extends localization.LocalizedReactComponent { } hide(); }; - request.open('POST', ToolImage.url(this.props.tool.value.id)); + request.open('POST', ToolImage.url(this.tool.id)); request.send(formData); return false; }; @@ -482,20 +581,20 @@ export default class Tool extends localization.LocalizedReactComponent { > {image} { - roleModel.writeAllowed(this.props.tool.value) && + roleModel.writeAllowed(this.tool) && + style={this.tool.iconId + ? {fontSize: 'xx-large', color: 'white', textShadow: '1px 1px black'} + : {fontSize: 'xx-large', color: '#888'} + } + /> } @@ -526,12 +625,12 @@ export default class Tool extends localization.LocalizedReactComponent { }} /> ); } else { - const shortDescription = this.props.tool.value.shortDescription; + const shortDescription = this.tool.shortDescription; if (shortDescription && shortDescription.trim().length) { return - {this.props.tool.value.shortDescription} ; + {this.tool.shortDescription} ; } else { return ); } else { - const description = this.props.tool.value.description; + const description = this.tool.description; if (description && description.trim().length) { return ( { - if (!roleModel.writeAllowed(this.props.tool.value) || this.link) { + if (!roleModel.writeAllowed(this.tool) || this.link) { return undefined; } const buttons = []; @@ -641,13 +740,13 @@ export default class Tool extends localization.LocalizedReactComponent { }; let shortDescriptionAndPullCommand; - const registry = this.registries.find(r => r.id === this.props.tool.value.registryId); - if (registry && roleModel.readAllowed(this.props.tool.value) && registry.pipelineAuth) { + const registry = this.registries.find(r => r.id === this.tool.registryId); + if (registry && roleModel.readAllowed(this.tool) && registry.pipelineAuth) { const renderPullCommand = () => { if (!registry) { return ; } - return `docker pull ${registry.externalUrl || registry.path}/${this.props.tool.value.image}`; + return `docker pull ${registry.externalUrl || registry.path}/${this.tool.image}`; }; shortDescriptionAndPullCommand = ( @@ -766,7 +865,7 @@ export default class Tool extends localization.LocalizedReactComponent { if (request.error) { message.error(request.error); } else { - await this.fetchVersions(); + await this.loadVersions(this.props.toolId); } resolve(); }); @@ -780,11 +879,11 @@ export default class Tool extends localization.LocalizedReactComponent { }; historyAvailableForUser = () => { - if (!this.props.tool.loaded) { + if (!this.tool) { return false; } - return roleModel.writeAllowed(this.props.tool.value) || - roleModel.executeAllowed(this.props.tool.value); + return roleModel.writeAllowed(this.tool) || + roleModel.executeAllowed(this.tool); }; getVersionScanningInfo = (item) => { @@ -829,8 +928,8 @@ export default class Tool extends localization.LocalizedReactComponent { @computed get isLastVersion () { - if (this.props.versions.loaded) { - return this.props.versions.value.versions.length === 1; + if (this.versions) { + return this.versions.length === 1; } return false; } @@ -838,14 +937,11 @@ export default class Tool extends localization.LocalizedReactComponent { @computed get toolVersionScanResults () { const data = []; - if (this.props.versions.loaded && - this.props.versions.value && - this.props.versions.value.versions) { + if (this.versions) { let keyIndex = 0; const versionsByDigest = {}; - const versions = this.props.versions.value.versions; - versions.forEach(version => { + this.versions.forEach(version => { if (version.attributes && version.attributes.digest) { if (!versionsByDigest[version.attributes.digest]) { versionsByDigest[version.attributes.digest] = []; @@ -854,7 +950,7 @@ export default class Tool extends localization.LocalizedReactComponent { } }); - versions.forEach(currentVersion => { + this.versions.forEach(currentVersion => { const scanResult = currentVersion.scanResult || {}; const versionAttributes = currentVersion.attributes; const { @@ -970,7 +1066,7 @@ export default class Tool extends localization.LocalizedReactComponent { if (request.error) { message.error(request.error, 5); } else { - await this.fetchVersions(); + await this.loadVersions(this.props.toolId); } resolve(); }); @@ -1092,7 +1188,7 @@ export default class Tool extends localization.LocalizedReactComponent { { !/^windows$/i.test(version.platform) && ( - this.isAdmin() || roleModel.isOwner(this.props.tool.value) + this.isAdmin() || roleModel.isOwner(this.tool) ) && !this.link && this.props.preferences.toolScanningEnabledForRegistry(this.dockerRegistry) && @@ -1109,7 +1205,7 @@ export default class Tool extends localization.LocalizedReactComponent { ) } { - roleModel.executeAllowed(this.props.tool.value) && + roleModel.executeAllowed(this.tool) && ( this.renderRunButton( version.name @@ -1117,7 +1213,7 @@ export default class Tool extends localization.LocalizedReactComponent { ) } { - roleModel.writeAllowed(this.props.tool.value) && !this.link && + roleModel.writeAllowed(this.tool) && !this.link && (