Skip to content

Commit

Permalink
React Triggers page [BIVS-2800] [BIVS-2808] (#1174)
Browse files Browse the repository at this point in the history
  • Loading branch information
moczolaszlo authored Oct 14, 2024
1 parent d36e5fe commit 64fba2b
Show file tree
Hide file tree
Showing 40 changed files with 1,562 additions and 646 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/bitrise-io/bitrise-workflow-editor

go 1.22.0

toolchain go1.22.5
toolchain go1.23.1

require (
github.com/GeertJohan/go.rice v1.0.3
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"stepDefinitions": "spec/integration"
},
"dependencies": {
"@bitrise/bitkit": "^13.159.0",
"@bitrise/bitkit": "^13.160.0",
"@bitrise/react2angular": "^5.0.0",
"@bitrise/steplib-search": "^2.3.0",
"@chakra-ui/react": "^2.8.2",
Expand Down
7 changes: 0 additions & 7 deletions rails/strings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -615,13 +615,6 @@ def strings
notification: "You can specify Env Vars which will only be available for the steps in your <workflow_id> Workflow."
}
},
triggers: {
update_deprecated_popup: {
title: "Triggers are changing for the better",
details_1: "We're converting your current trigger maps to the new format, to enable specifying Pushes and Pull Requests separately, as well as setting the source and target branch for PRs. You don't have to worry, though, everything you've set so far will work the same!",
details_2: "For more information, please check the <a href='<url>' target='_blank'>blogpost</a>!"
}
},
stack: {
load_stacks_progress: {
in_progress: "Loading, wait a sec..."
Expand Down
9 changes: 2 additions & 7 deletions source/javascripts/_componentRegister.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,8 @@ angular
.component(
'rTriggersPage',
register(TriggersPage, [
'onTriggerMapChange',
'pipelines',
'triggerMap',
'setDiscard',
'workflows',
'isWebsiteMode',
'integrationsUrl',
"onChange",
"yml",
]),
)
.component(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { EnvVar } from '@/core/models/EnvVar';
export enum WorkflowConfigTab {
CONFIGURATION = 'configuration',
PROPERTIES = 'properties',
TRIGGERS = 'triggers',
}

export type FormValues = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import omit from 'lodash/omit';
import useSearchParams from '@/hooks/useSearchParams';
import useBitriseYmlStore from '@/hooks/useBitriseYmlStore';
import { EnvVar } from '@/core/models/EnvVar';
import TriggersTabPanel from '@/pages/WorkflowsPage/components/WorkflowConfigPanel/components/TriggersTabPanel';
import useFeatureFlag from '@/hooks/useFeatureFlag';
import WorkflowConfigHeader from './components/WorkflowConfigHeader';
import ConfigurationTab from './tabs/ConfigurationTab';
import PropertiesTab from './tabs/PropertiesTab';
Expand Down Expand Up @@ -66,6 +68,8 @@ const WorkflowConfigPanelContent = () => {
updateWorkflowEnvVars,
]);

const isTargetBasedTriggersEnabled = useFeatureFlag('enable-target-based-triggers');

return (
<Tabs display="flex" flexDir="column" borderLeft="1px solid" borderColor="border/regular">
<WorkflowConfigHeader variant="panel" />
Expand All @@ -76,6 +80,11 @@ const WorkflowConfigPanelContent = () => {
<TabPanel id={WorkflowConfigTab.PROPERTIES} p="24" overflowY="auto" h="100%">
<PropertiesTab />
</TabPanel>
{isTargetBasedTriggersEnabled && (
<TabPanel id={WorkflowConfigTab.TRIGGERS} overflowY="auto" h="100%">
<TriggersTabPanel />
</TabPanel>
)}
</TabPanels>
</Tabs>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Box, IconButton, Tab, TabList, Text } from '@bitrise/bitkit';
import WorkflowService from '@/core/models/WorkflowService';
import useDependantWorkflows from '@/hooks/useDependantWorkflows';
import { useWorkflowsPageStore } from '@/pages/WorkflowsPage/WorkflowsPage.store';
import useFeatureFlag from '@/hooks/useFeatureFlag';
import { useWorkflowConfigContext } from '../WorkflowConfig.context';
import { WorkflowConfigTab } from '../WorkflowConfig.types';

Expand All @@ -13,8 +14,10 @@ const WorkflowConfigHeader = ({ variant }: Props) => {
const { id, userValues } = useWorkflowConfigContext() ?? { id: '' };
const dependants = useDependantWorkflows(id);
const { openDeleteWorkflowDialog } = useWorkflowsPageStore();
const isTargetBasedTriggersEnabled = useFeatureFlag('enable-target-based-triggers');

const shouldShowDeleteButton = variant === 'panel';
const shouldShowTriggersTab = variant === 'panel' && isTargetBasedTriggersEnabled;

return (
<>
Expand All @@ -39,12 +42,11 @@ const WorkflowConfigHeader = ({ variant }: Props) => {
/>
)}
</Box>
<Box position="relative" mt="8">
<TabList paddingX="8">
<Tab id={WorkflowConfigTab.CONFIGURATION}>Configuration</Tab>
<Tab id={WorkflowConfigTab.PROPERTIES}>Properties</Tab>
</TabList>
</Box>
<TabList paddingX="8" position="relative" mt="8">
<Tab id={WorkflowConfigTab.CONFIGURATION}>Configuration</Tab>
<Tab id={WorkflowConfigTab.PROPERTIES}>Properties</Tab>
{shouldShowTriggersTab && <Tab id={WorkflowConfigTab.TRIGGERS}>Triggers</Tab>}
</TabList>
</>
);
};
Expand Down
55 changes: 25 additions & 30 deletions source/javascripts/controllers/_MainController.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {segmentTrack} from "@/utils/segmentTracking";
id: "workflows",
title: "<%= data[:strings][:main][:menus][:workflows] %>",
path: "<%= data[:routes][:endpoints][:workflows] %>",
possibleURLParameterKeys: ["workflow_id"],
possibleURLParameterKeys: ["workflow_id", "tab"],
cssClass: "workflows"
},
{
Expand Down Expand Up @@ -207,7 +207,6 @@ import {segmentTrack} from "@/utils/segmentTracking";
break;
}
case "env-vars":
case "triggers":
var loadPromises = [appService.getAppConfig()];
if (requestService.isWebsiteMode()) {
loadPromises.push(Stack.getAll());
Expand All @@ -225,37 +224,28 @@ import {segmentTrack} from "@/utils/segmentTracking";

loadPromise.then(
function () {
$q(function (deprecatedTriggerCheckResolve, deprecatedTriggerCheckReject) {
if (appService.appConfigHasDeprecatedTriggerMap()) {
appService.updateDeprecatedTriggerMap();

Popup.showNoticePopup("<%= data[:strings][:triggers][:update_deprecated_popup][:title] %>", [
"<%= data[:strings][:triggers][:update_deprecated_popup][:details_1] %>",
"<%= replaced_string(data[:strings][:triggers][:update_deprecated_popup][:details_2], [data[:routes][:blog][:new_triggers]])%>"
])
.then(function () {
return requestService.isWebsiteMode() && appService.pipelineConfig.usesRepositoryYml
? $q.when()
: viewModel.save({source: "deprecated_trigger_map_update"});
})
.then(deprecatedTriggerCheckResolve, deprecatedTriggerCheckReject);
} else {
deprecatedTriggerCheckResolve();
}
}).then(
function () {
resolve();
},
function (error) {
reject(error);
}
);
resolve();
},
function (error) {
reject(error);
}
);
break;
case "triggers":
var loadPromises = [appService.getAppConfig()];
if (requestService.isWebsiteMode()) {
loadPromises.push(appService.getPipelineConfig());
}
var loadPromise = $q.all(loadPromises);

loadPromise.then(
function () {
resolve();
},
function (error) {
reject(error);
}
);
break;
case "licenses":
var loadPromises = [appService.getAppConfig(), appService.getPipelineConfig(), appService.getPublicApiToken()];
Expand Down Expand Up @@ -318,7 +308,7 @@ import {segmentTrack} from "@/utils/segmentTracking";
);
}

viewModel.menuSelected = function (menu) {
viewModel.menuSelected = function (menu, params) {
if (menu === viewModel.currentMenu) {
return;
}
Expand Down Expand Up @@ -414,7 +404,12 @@ import {segmentTrack} from "@/utils/segmentTracking";

viewModel.currentMenu = menu;
if ($location.path() != "/" + menu.path) {
$location.path("/" + menu.path).replace();
if (params) {
$location.path("/" + menu.path).search(params).replace();
}
else {
$location.path("/" + menu.path).replace();
}
}

if (!isInitialSelection) {
Expand Down Expand Up @@ -936,7 +931,7 @@ import {segmentTrack} from "@/utils/segmentTracking";
const menu = viewModel.menus.find(m => `/${m.path}` === e.detail.path);

if (menu) {
viewModel.menuSelected(menu);
viewModel.menuSelected(menu, e.detail.params);
}
});

Expand Down
41 changes: 15 additions & 26 deletions source/javascripts/controllers/_TriggersController.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,31 @@
import {safeDigest} from "@/services/react-compat";

(function() {
"use strict";

angular
.module("BitriseWorkflowEditor")
.controller("TriggersController", function($scope, $rootScope, $location, appService, Progress, Trigger, launchDarklyService, requestService) {
.controller("TriggersController", function($rootScope, $scope, appService) {
var viewModel = this;
viewModel.pipelines = appService.appConfig.pipelines ? Object.keys(appService.appConfig.pipelines) : [];
viewModel.workflows = Object.keys(appService.appConfig.workflows).filter(function(workflowID) {
return !workflowID.startsWith('_');
});
viewModel.triggerMap = appService.appConfig.trigger_map;
viewModel.isWebsiteMode = requestService.mode === 'website';
viewModel.yml = null;

viewModel.originalTriggerMap = appService.appConfig.trigger_map;
viewModel.integrationsUrl = appService.appDetails ? '/app/' + appService.appDetails.slug + '/settings/integrations?tab=webhooks' : '';
viewModel.init = function () {
viewModel.yml = appService.appConfig;
};

$scope.$on(
"$destroy",
$rootScope.$on("MainController::changesDiscarded", function() {
appService.appConfig.trigger_map = viewModel.originalTriggerMap;
viewModel.onDiscard(viewModel.originalTriggerMap);
})
);
viewModel.onChangeYml = (yml) => {
appService.appConfig = yml;
safeDigest($rootScope);
}

$scope.$on(
"$destroy",
$rootScope.$on("MainController::savedFinishedWithSuccess", function() {
viewModel.originalTriggerMap = appService.appConfig.trigger_map;
$rootScope.$on("MainController::changesDiscarded", function() {
safeDigest($scope);
viewModel.init();
})
);

viewModel.setDiscard = function(onDiscard) {
viewModel.onDiscard = onDiscard;
}

viewModel.onTriggerMapChange = function(triggerMap) {
appService.appConfig.trigger_map = triggerMap;
$scope.$apply();
};
viewModel.init();
});
})();
72 changes: 71 additions & 1 deletion source/javascripts/core/models/BitriseYml.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,74 @@ const ChainableMockYml: BitriseYml = {
},
};

export { MockYml, ChainableMockYml };
const MockYmlWithTriggers: BitriseYml = {
...MockYml,
trigger_map: [
{
workflow: 'wf1',
push_branch: 'master',
},
{
workflow: 'wf2',
push_branch: 'release',
},
{
workflow: 'wf3',
pull_request_target_branch: '*',
},
],
workflows: {
a_release_IOS: {
triggers: {
push: [
{
branch: 'main',
enabled: false,
},
],
tag: [
{
name: {
regex: '^\\d\\.\\d\\.\\d$',
},
},
],
pull_request: [
{
comment: '[workflow: deploy]',
},
{
commit_message: {
regex: '.*\\[workflow: deploy\\].*',
},
},
],
},
},
c_staging_IOS: {
triggers: {
pull_request: [
{
target_branch: 'main',
source_branch: 'approved',
enabled: false,
},
],
},
},
},
pipelines: {
b_staging_IOS: {
triggers: {
push: [
{
branch: 'staging',
enabled: false,
},
],
},
},
},
};

export { MockYml, ChainableMockYml, MockYmlWithTriggers };
Loading

0 comments on commit 64fba2b

Please sign in to comment.