From e8f8ee93a17d9e8c8d6cb7c64957d6d2c5bf61c8 Mon Sep 17 00:00:00 2001 From: Nataly Shrits Date: Thu, 14 Dec 2017 11:53:22 +0200 Subject: [PATCH] Alias feature (#686) * improve error handling in editor * update git Dockerfile * fix compose files * add api support for linked keys * add management support for linked keys * [editor] redirect link keys * organize files * add authoring support for linked keys * [editor] display linked keys * Added api and management unit tests * rename 'link' key type to 'alias' * added key aliases test * combine dependents endpoints * [editor] handle alias value type * added more tests * [editor] deleting a key should delete aliases * [editor] move keyPath validation to NewKeyInput component * [editor] Alert component can display custom components * [editor] added addAlias action to selectedKey duck * [editor] added validation and component data to Alert component * [editor] NewKeyInput styles * [editor] added option to add alias for key * [e2e-ui] fix aliases tests * [e2e-ui] added add alias test * [editor] style review * [authoring] fix delete single key * [editor] added delete alias * [e2e-ui] added delete alias test * [e2e-integration] rename test key * [smoke-tests] rename test keys * [e2e-integration] added alias test * code review * bump versions --- core/Engine/Tweek.Engine.Core/Rules/Utils.cs | 5 +- .../Core/KeyAliasParserTests.cs | 32 ++ deployments/dev/docker-compose.e2e.yml | 2 - deployments/dev/docker-compose.override.yml | 2 + .../spec/authoring-api/add-app.test.js | 62 ++-- .../authoring-api/app-permissions.test.js | 206 +++++------ .../authoring-api/bulk-keys-upload.test.js | 75 ++-- e2e/integration/spec/setup.js | 3 + .../spec/tweek-api/key-aliases.test.js | 19 + e2e/ui/spec/keys/add-key.js | 3 + e2e/ui/spec/keys/delete-key.js | 11 +- e2e/ui/spec/keys/dependent-keys.js | 8 +- e2e/ui/spec/keys/key-aliases.js | 60 ++++ e2e/ui/spec/keys/keys-list.js | 5 +- e2e/ui/spec/keys/routing.js | 3 +- e2e/ui/utils/Key.js | 38 +- e2e/ui/utils/KeysList.js | 50 +++ e2e/ui/utils/browser-extension-commands.js | 8 +- e2e/ui/yarn.lock | 16 +- .../GetConfigurations/HiddenKeysTests.cs | 8 +- .../GetConfigurations/KeyPathsTests.cs | 26 +- .../IdentityBasedTestsContextProvider.cs | 6 +- .../Models/RulesBasedTestsContextProvider.cs | 24 +- .../GetConfigurations/RuleBasedKeysTests.cs | 2 +- .../ValueDistributionTests.cs | 4 +- services/api/Tweek.ApiService/Startup.cs | 3 +- .../Tweek.ApiService/Tweek.ApiService.csproj | 2 +- services/authoring/package.json | 2 +- .../src/repositories/keys-repository.ts | 59 ++-- services/authoring/src/routes/keys.ts | 13 +- services/authoring/src/routes/schema.ts | 2 +- services/authoring/src/search-index/index.ts | 41 ++- .../authoring/test/keys-repository-spec.js | 6 +- services/editor/package.json | 2 +- .../utils/request-error-handling-wrapper.js | 2 +- .../spec/unit/store/ducks/selectedKey-spec.js | 35 +- .../key-name-validations-spec.js | 12 +- .../editor/src/components/alerts/Alerts.js | 79 +++-- .../common}/EditableText/EditableText.css | 0 .../common/EditableText/EditableText.js | 58 +++ .../common}/EditableText/EditableText.less | 2 +- .../EditableTextArea/EditableTextArea.css | 0 .../EditableTextArea/EditableTextArea.js | 9 +- .../EditableTextArea/EditableTextArea.less | 2 +- .../KeyPage/KeyAddPage/KeyAddPage.css | 333 ------------------ .../KeyPage/KeyAddPage/KeyAddPage.js | 32 +- .../KeyPage/KeyAddPage/KeyAddPage.less | 11 - .../KeyValueTypeSelector.css | 0 .../KeyValueTypeSelector.js | 15 +- .../KeyValueTypeSelector.less | 0 .../KeyPage/KeyAddPage/NewKeyInput.css | 333 ++++++++++++++++++ .../KeyPage/KeyAddPage/NewKeyInput.js | 69 ++++ .../KeyPage/KeyAddPage/NewKeyInput.less | 12 + .../KeyAddPage}/key-name-validations.js | 4 +- .../DependencyIndicator.css | 59 +--- .../DependencyIndicator.js | 89 +++-- .../DependencyIndicator.less | 47 ++- .../KeyEditPage/EditableText/EditableText.js | 55 --- .../KeyPage/KeyEditPage/HeaderMainInput.js | 7 +- .../KeyPage/KeyEditPage/KeyEditPage.css | 85 ----- .../KeyPage/KeyEditPage/KeyEditPage.js | 43 ++- .../KeyPage/KeyEditPage/KeyEditPage.less | 37 -- .../KeyPageActions/KeyPageActions.css | 55 +-- .../KeyPageActions/KeyPageActions.js | 93 +++-- .../KeyPageActions/KeyPageActions.less | 24 +- .../KeyPage/KeyEditPage/NewKeyInput.js | 54 --- services/editor/src/resources/alert-icon.svg | 20 +- .../editor/src/resources/archive-icon.svg | 8 + services/editor/src/resources/key-icon.svg | 19 +- services/editor/src/resources/link-icon.svg | 7 + .../editor/src/resources/restore-icon.svg | 9 + services/editor/src/resources/trash-icon.svg | 11 + .../editor/src/services/context-service.js | 4 +- services/editor/src/services/types-service.js | 11 +- services/editor/src/store/ducks/alerts.js | 8 +- .../ducks/ducks-utils/blankKeyDefinition.js | 36 +- .../editor/src/store/ducks/selectedKey.js | 121 +++++-- services/editor/yarn.lock | 183 +++++++--- .../git-service/BareRepository/Dockerfile | 45 ++- .../auth/@global/read_configuration.json | 1 - .../@tweek/auth/@global/write_context.json | 1 - .../auth/tweek_editor_user/write_context.json | 1 - .../@tweek/custom_types/version.json | 1 - .../editor/google_tag_manager/enabled.json | 3 +- .../@tweek/editor/google_tag_manager/id.json | 3 +- .../@tweek/editor/history/since.json | 1 - .../@tweek/editor/search/max_results.json | 1 - .../editor/service_worker/is_enabled.json | 1 - .../@tweek/editor/show_internal_keys.json | 1 - .../source/manifests/@tweek/schema/user.json | 1 - .../git-service/BareRepository/sshd_config | 1 - .../display/depends_on_alias.jpad | 13 + .../identity_context/color.jpad | 0 .../rule_based_keys/comparison.jpad | 0 .../rule_based_keys/in.jpad | 0 .../rule_based_keys/multi_conditions.jpad | 0 .../rule_based_keys/simple.jpad | 0 .../value_distribution/bernoulli.jpad | 0 .../weighted_normalized.jpad | 0 .../auth/@global/read_configuration.json | 1 - .../@tweek/auth/@global/write_context.json | 1 - .../auth/tweek_editor_user/write_context.json | 1 - .../@tweek/custom_types/version.json | 1 - .../editor/google_tag_manager/enabled.json | 3 +- .../@tweek/editor/google_tag_manager/id.json | 3 +- .../@tweek/editor/history/since.json | 1 - .../@tweek/editor/search/max_results.json | 1 - .../editor/service_worker/is_enabled.json | 1 - .../@tweek/editor/show_internal_keys.json | 1 - .../@tweek/schema/delete_property_test.json | 1 - .../@tweek/schema/edit_properties_test.json | 1 - .../manifests/@tweek/schema/other.json | 1 - .../manifests/@tweek/schema/user.json | 1 - .../test_category/test_key1.json | 1 - .../test_category/test_key2.json | 1 - .../test_category2/user_fruit.json | 1 - .../behavior_tests/context/override_key.json | 3 +- .../behavior_tests/delete_key/archive.json | 3 +- .../delete_key/delete/accepted.json | 3 +- .../delete_key/delete/alias.json | 10 + .../delete_key/delete/canceled.json | 3 +- .../delete_key/delete/not_accepted.json | 3 +- .../behavior_tests/delete_key/unarchive.json | 3 +- .../dependent_keys/display/alias_key.json | 10 + .../dependent_keys/display/depends_on.json | 1 - .../display/depends_on_alias.json | 18 + .../dependent_keys/display/used_by.json | 1 - .../dependent_keys/fail/first.json | 1 - .../dependent_keys/fail/second.json | 1 - .../dependent_keys/fail/third.json | 1 - .../dependent_keys/pass/depends_on.json | 1 - .../dependent_keys/pass/used_by.json | 1 - .../edit_key/text/edit_test.json | 1 - .../edit_key/visual/const/number_type.json | 3 +- .../edit_key/visual/const/object_type.json | 3 +- .../edit_key/visual/const/string_type.json | 3 +- .../edit_key/visual/edit_test.json | 1 - .../behavior_tests/key_aliases/alias_key.json | 10 + .../key_aliases/alias_to_alias.json | 10 + .../key_aliases/delete_alias.json | 10 + .../key_aliases/regular_key.json | 15 + .../behavior_tests/keys_list/banana.json | 1 - .../behavior_tests/keys_list/green_apple.json | 1 - .../behavior_tests/keys_list/red_apple.json | 1 - .../partitions/add_partition.json | 1 - .../partitions/add_partition_group.json | 1 - .../partitions/delete_partition.json | 1 - .../partitions/empty_partition.json | 1 - .../partitions/partition_groups.json | 1 - .../manifests/behavior_tests/read_only.json | 1 - .../behavior_tests/revision_history.json | 1 - .../manifests/behavior_tests/routing.json | 3 +- .../manifests/behavior_tests/tags.json | 3 +- .../integration_tests/alias_key.json | 10 + .../some_key.json | 7 +- .../identity_context/color.json | 3 +- .../key_path/key1.json | 3 +- .../key_path/key2.json | 3 +- .../key_path_.json | 3 +- .../key_path_suffix/key.json | 3 +- .../not_hidden/@hidden/@hidden_key.json | 3 +- .../not_hidden/@hidden/visible_key.json | 3 +- .../not_hidden/@some_hidden_key.json | 3 +- .../not_hidden/some_key.json | 3 +- .../rule_based_keys/comparison.json | 3 +- .../rule_based_keys/in.json | 3 +- .../rule_based_keys/multi_conditions.json | 3 +- .../rule_based_keys/simple.json | 3 +- .../value_distribution/bernoulli.json | 3 +- .../weighted_normalized.json | 3 +- services/management/package.json | 2 +- .../management/src/build-rules-artifiact.js | 53 ++- .../test/build-rules-artifact-spec.js | 13 + 173 files changed, 1790 insertions(+), 1471 deletions(-) create mode 100644 core/Engine/Tweek.Engine.Tests/Core/KeyAliasParserTests.cs create mode 100644 e2e/integration/spec/tweek-api/key-aliases.test.js create mode 100644 e2e/ui/spec/keys/key-aliases.js create mode 100644 e2e/ui/utils/KeysList.js rename services/editor/spec/unit/{store/ducks/ducks-utils => utils}/key-name-validations-spec.js (84%) rename services/editor/src/{pages/keys/components/KeyPage/KeyEditPage => components/common}/EditableText/EditableText.css (100%) create mode 100644 services/editor/src/components/common/EditableText/EditableText.js rename services/editor/src/{pages/keys/components/KeyPage/KeyEditPage => components/common}/EditableText/EditableText.less (78%) rename services/editor/src/{pages/keys/components/KeyPage/KeyEditPage => components/common}/EditableTextArea/EditableTextArea.css (100%) rename services/editor/src/{pages/keys/components/KeyPage/KeyEditPage => components/common}/EditableTextArea/EditableTextArea.js (89%) rename services/editor/src/{pages/keys/components/KeyPage/KeyEditPage => components/common}/EditableTextArea/EditableTextArea.less (83%) rename services/editor/src/pages/keys/components/KeyPage/{KeyEditPage => KeyAddPage}/KeyValueTypeSelector/KeyValueTypeSelector.css (100%) rename services/editor/src/pages/keys/components/KeyPage/{KeyEditPage => KeyAddPage}/KeyValueTypeSelector/KeyValueTypeSelector.js (84%) rename services/editor/src/pages/keys/components/KeyPage/{KeyEditPage => KeyAddPage}/KeyValueTypeSelector/KeyValueTypeSelector.less (100%) create mode 100644 services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.css create mode 100644 services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.js create mode 100644 services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.less rename services/editor/src/{store/ducks/ducks-utils/validations => pages/keys/components/KeyPage/KeyAddPage}/key-name-validations.js (87%) delete mode 100644 services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.js delete mode 100644 services/editor/src/pages/keys/components/KeyPage/KeyEditPage/NewKeyInput.js create mode 100644 services/editor/src/resources/archive-icon.svg create mode 100644 services/editor/src/resources/link-icon.svg create mode 100644 services/editor/src/resources/restore-icon.svg create mode 100644 services/editor/src/resources/trash-icon.svg create mode 100644 services/git-service/BareRepository/tests-source/implementations/jpad/behavior_tests/dependent_keys/display/depends_on_alias.jpad rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/identity_context/color.jpad (100%) rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/rule_based_keys/comparison.jpad (100%) rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/rule_based_keys/in.jpad (100%) rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/rule_based_keys/multi_conditions.jpad (100%) rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/rule_based_keys/simple.jpad (100%) rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/value_distribution/bernoulli.jpad (100%) rename services/git-service/BareRepository/tests-source/implementations/jpad/{@smoke_tests => smoke_tests}/value_distribution/weighted_normalized.jpad (100%) create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/alias.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/alias_key.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on_alias.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_key.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_to_alias.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/delete_alias.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/regular_key.json create mode 100644 services/git-service/BareRepository/tests-source/manifests/integration_tests/alias_key.json rename services/git-service/BareRepository/tests-source/manifests/{@integration_tests => integration_tests}/some_key.json (57%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/identity_context/color.json (75%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/key_path/key1.json (77%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/key_path/key2.json (77%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/key_path_.json (78%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/key_path_suffix/key.json (76%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/not_hidden/@hidden/@hidden_key.json (73%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/not_hidden/@hidden/visible_key.json (74%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/not_hidden/@some_hidden_key.json (75%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/not_hidden/some_key.json (76%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/rule_based_keys/comparison.json (74%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/rule_based_keys/in.json (76%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/rule_based_keys/multi_conditions.json (72%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/rule_based_keys/simple.json (75%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/value_distribution/bernoulli.json (73%) rename services/git-service/BareRepository/tests-source/manifests/{@smoke_tests => smoke_tests}/value_distribution/weighted_normalized.json (71%) diff --git a/core/Engine/Tweek.Engine.Core/Rules/Utils.cs b/core/Engine/Tweek.Engine.Core/Rules/Utils.cs index 12369c7a8..f96f7cbc1 100644 --- a/core/Engine/Tweek.Engine.Core/Rules/Utils.cs +++ b/core/Engine/Tweek.Engine.Core/Rules/Utils.cs @@ -9,10 +9,13 @@ namespace Tweek.Engine.Core.Rules { public static class Utils { - public static IRuleParser ConstValueParser = new AnonymousParser(str => + public static readonly IRuleParser ConstValueParser = new AnonymousParser(str => Prelude.map(JsonValue.From(JToken.Parse(str)), (value) => new AnonymousRule(ctx => ConfigurationValue.New(value)))); + public static readonly IRuleParser KeyAliasParser = new AnonymousParser(originalKey => + new AnonymousRule(ctx => ctx($"keys.{originalKey}").Map(ConfigurationValue.New))); + public class AnonymousRule : IRule { private readonly Func> fn; diff --git a/core/Engine/Tweek.Engine.Tests/Core/KeyAliasParserTests.cs b/core/Engine/Tweek.Engine.Tests/Core/KeyAliasParserTests.cs new file mode 100644 index 000000000..1922621f0 --- /dev/null +++ b/core/Engine/Tweek.Engine.Tests/Core/KeyAliasParserTests.cs @@ -0,0 +1,32 @@ +using LanguageExt; +using Tweek.Engine.Core.Context; +using Xunit; +using static LanguageExt.Prelude; + +namespace Tweek.Engine.Tests.Core +{ + public class KeyAliasParserTests + { + [Fact] + public void ParseLink_GetLinkValue() + { + // Arrange + const string ORIGINAL_KEY = "some_key"; + var parser = Engine.Core.Rules.Utils.KeyAliasParser; + + string requestedContext = null; + var getContextValue = new GetContextValue(key => + { + requestedContext = key; + return None; + }); + + // Act + var result = parser.Parse(ORIGINAL_KEY).GetValue(getContextValue); + + // Assert + Assert.Equal(result, None); + Assert.Equal(requestedContext, $"keys.{ORIGINAL_KEY}"); + } + } +} \ No newline at end of file diff --git a/deployments/dev/docker-compose.e2e.yml b/deployments/dev/docker-compose.e2e.yml index bb2aaef59..02748c2a5 100644 --- a/deployments/dev/docker-compose.e2e.yml +++ b/deployments/dev/docker-compose.e2e.yml @@ -4,7 +4,6 @@ services: management: environment: - GIT_URL=ssh://git@git/tweek/tests - - GIT_SAMPLE_INTERVAL=500 editor: environment: @@ -20,7 +19,6 @@ services: api: environment: - - Rules__SampleIntervalInMs=500 - CorsPolicies__Keys__Origins=http://editor:3000,http://testorigin - CorsPolicies__Keys__Methods=GET - CorsPolicies__Keys__MaxPreflightAge=60 diff --git a/deployments/dev/docker-compose.override.yml b/deployments/dev/docker-compose.override.yml index 56dcb7c1c..d859925de 100644 --- a/deployments/dev/docker-compose.override.yml +++ b/deployments/dev/docker-compose.override.yml @@ -30,6 +30,7 @@ services: - GIT_URL=ssh://git@git/tweek/repo - GIT_PUBLIC_KEY_PATH=/run/secrets/tweek_ssh_public_key - GIT_PRIVATE_KEY_PATH=/run/secrets/tweek_ssh_private_key + - GIT_SAMPLE_INTERVAL=500 - MINIO_ENDPOINT=minio:9000 - MINIO_ACCESS_KEY_PATH=/run/secrets/minio_access_key - MINIO_SECRET_KEY_PATH=/run/secrets/minio_secret_key @@ -58,6 +59,7 @@ services: - Rules__Minio__SecretKeyPath=/run/secrets/minio_secret_key - Rules__Nats__Endpoint=nats://nats:4222 - Rules__Management__Url=http://management:3000 + - Rules__SampleIntervalInMs=500 - Rules__FailureDelayInMs=50 - Rules__VersionTimeoutInMs=2000 - UseAddon__Rules=MinioRules diff --git a/e2e/integration/spec/authoring-api/add-app.test.js b/e2e/integration/spec/authoring-api/add-app.test.js index 46a2be59d..c154e5983 100644 --- a/e2e/integration/spec/authoring-api/add-app.test.js +++ b/e2e/integration/spec/authoring-api/add-app.test.js @@ -1,45 +1,37 @@ -const chai = require('chai'); -chai.should(); -const {init:initClients} = require("../../utils/clients"); -const delay = (duration)=> new Promise(resolve=>setTimeout(resolve,duration)); +const { init: initClients } = require('../../utils/clients'); -describe('authoring api', () => { +describe('authoring api - add app', () => { let clients; before(async () => { clients = await initClients(); }); - describe('/posts /apps/new', () => { - it('allow creating new app with keys-read permission', async () => { - const response = await clients.authoring.post('/api/apps?author.name=test&author.email=test@soluto.com') - .send({ name: 'my-app', permissions: ['keys-read'] }) - .expect(200); - - let {appId, appSecret} = response.body; - - let appClient = await clients.authoring.with(client => - client.set( {"x-client-id": appId, "x-client-secret": appSecret } ) - .unset("Authorization") - ); - - await appClient.get('/api/keys/@integration_tests/some_key') - .expect(200) - - await appClient.get('/api/keys') - .expect(403) - }); - - it('allow creating new app with invalid permission', async () => { - await clients.authoring.post('/api/apps?author.name=test&author.email=test@soluto.com') - .send({ name: 'my-app', permissions: ['admin'] }) - .expect(400); - - await clients.authoring.post('/api/apps?author.name=test&author.email=test@soluto.com') - .send({ name: 'my-app', permissions: ['my-permission'] }) - .expect(400); - - }); + it('allow creating new app with keys-read permission', async () => { + const response = await clients.authoring + .post('/api/apps?author.name=test&author.email=test@soluto.com') + .send({ name: 'my-app', permissions: ['keys-read'] }) + .expect(200); + let { appId, appSecret } = response.body; + + let appClient = await clients.authoring.with(client => + client.set({ 'x-client-id': appId, 'x-client-secret': appSecret }).unset('Authorization'), + ); + + await appClient.get('/api/keys/integration_tests/some_key').expect(200); + + await appClient.get('/api/keys').expect(403); }); + it('allow creating new app with invalid permission', async () => { + await clients.authoring + .post('/api/apps?author.name=test&author.email=test@soluto.com') + .send({ name: 'my-app', permissions: ['admin'] }) + .expect(400); + + await clients.authoring + .post('/api/apps?author.name=test&author.email=test@soluto.com') + .send({ name: 'my-app', permissions: ['my-permission'] }) + .expect(400); + }); }); diff --git a/e2e/integration/spec/authoring-api/app-permissions.test.js b/e2e/integration/spec/authoring-api/app-permissions.test.js index a31d7e7ae..0526412a7 100644 --- a/e2e/integration/spec/authoring-api/app-permissions.test.js +++ b/e2e/integration/spec/authoring-api/app-permissions.test.js @@ -1,131 +1,131 @@ -const { init: initClients } = require("../../utils/clients"); -const permissions = ['keys-list', 'keys-read', 'keys-write', 'schemas-read', 'schemas-write', 'history', 'search', 'search-index', 'tags-read', 'tags-write']; +const { init: initClients } = require('../../utils/clients'); +const permissions = [ + 'keys-list', + 'keys-read', + 'keys-write', + 'schemas-read', + 'schemas-write', + 'history', + 'search', + 'search-index', + 'tags-read', + 'tags-write', +]; const { expect } = require('chai'); -describe("app permissions test", () => { - let clients; - before(async () => { - clients = await initClients(); - }); - const cases = [{ - name: "read_specific_key", - requirePermission: "keys-read", - action: async (client) => { - await client.get('/api/keys/@integration_tests/some_key') - .expect(200) - } +describe('authoring api - app permissions', () => { + let clients; + before(async () => { + clients = await initClients(); + }); + const cases = [ + { + name: 'read_specific_key', + requirePermission: 'keys-read', + action: async client => { + await client.get('/api/keys/integration_tests/some_key').expect(200); + }, }, { - name: "read_specific_key", - requirePermission: "keys-read", - action: async (client) => { - await client.get('/api/key?keyPath=%40integration_tests%2Fsome_key') - .expect(200) - } + name: 'read_specific_key', + requirePermission: 'keys-read', + action: async client => { + await client.get('/api/key?keyPath=integration_tests%2Fsome_key').expect(200); + }, }, { - name: "read_manifests", - requirePermission: "keys-read", - action: async (client) => { - await client.get('/api/manifests/@integration_tests/some_key') - .expect(200) - } + name: 'read_manifests', + requirePermission: 'keys-read', + action: async client => { + await client.get('/api/manifests/integration_tests/some_key').expect(200); + }, }, { - name: "list_keys", - requirePermission: "keys-list", - action: async (client) => { - await client.get('/api/keys') - .expect(200) - } + name: 'list_keys', + requirePermission: 'keys-list', + action: async client => { + await client.get('/api/keys').expect(200); + }, }, { - name: "list_manifests", - requirePermission: "keys-list", - action: async (client) => { - await client.get('/api/manifests') - .expect(200) - } + name: 'list_manifests', + requirePermission: 'keys-list', + action: async client => { + await client.get('/api/manifests').expect(200); + }, }, { - name: "get_dependents", - requirePermission: "keys-read", - action: async (client) => { - await client.get('/api/dependents/@integration_tests/some_key') - .expect(200) - } + name: 'get_dependents', + requirePermission: 'keys-read', + action: async client => { + await client.get('/api/dependents/integration_tests/some_key').expect(200); + }, }, { - name: "get_dependents", - requirePermission: "keys-read", - action: async (client) => { - await client.get('/api/dependents/@integration_tests/some_key') - .expect(200) - } + name: 'get_dependents', + requirePermission: 'keys-read', + action: async client => { + await client.get('/api/dependents/integration_tests/some_key').expect(200); + }, }, { - name: "get_schemas", - requirePermission: "schemas_read", - action: async (client) => { - await client.get('/api/schemas') - .expect(200) - } + name: 'get_schemas', + requirePermission: 'schemas_read', + action: async client => { + await client.get('/api/schemas').expect(200); + }, }, { - name: "search", - requirePermission: "search", - action: async (client) => { - await client.get('/api/search') - .expect(200) - } + name: 'search', + requirePermission: 'search', + action: async client => { + await client.get('/api/search').expect(200); + }, }, { - name: "suggestions", - requirePermission: "search", - action: async (client) => { - await client.get('/api/suggestions') - .expect(200) - } + name: 'suggestions', + requirePermission: 'search', + action: async client => { + await client.get('/api/suggestions').expect(200); + }, }, { - name: "search-index", - requirePermission: "search-index", - action: async (client) => { - await client.get('/api/search-index') - .expect(200) - } - } - ]; - - for (let permission of permissions) { - it(`testing permission ${permission}`, async () => { - - const relevantCases = cases.filter(c => c.requirePermission === permission); - const forbiddenCases = cases.filter(c => c.requirePermission !== permission); + name: 'search-index', + requirePermission: 'search-index', + action: async client => { + await client.get('/api/search-index').expect(200); + }, + }, + ]; - let response = await clients.authoring.post('/api/apps?author.name=test&author.email=test@soluto.com') - .send({ name: 'my-app', permissions: [permission] }) - .expect(200); - + for (let permission of permissions) { + it(`testing permission ${permission}`, async () => { + const relevantCases = cases.filter(c => c.requirePermission === permission); + const forbiddenCases = cases.filter(c => c.requirePermission !== permission); - let { appId, appSecret } = response.body; + let response = await clients.authoring + .post('/api/apps?author.name=test&author.email=test@soluto.com') + .send({ name: 'my-app', permissions: [permission] }) + .expect(200); - let appClient = await clients.authoring.with(client => - client.set({ "x-client-id": appId, "x-client-secret": appSecret }) - .unset("Authorization") - ); + let { appId, appSecret } = response.body; - await Promise.all(relevantCases.map(x=> x.action(appClient))) - - await Promise.all(forbiddenCases.map(async x=> { - await x.action(appClient).then(()=>true, ex=> { - return expect(ex.message).to.contain("403"); - }) - })); - - - }).timeout(6000); - } + let appClient = await clients.authoring.with(client => + client.set({ 'x-client-id': appId, 'x-client-secret': appSecret }).unset('Authorization'), + ); + await Promise.all(relevantCases.map(x => x.action(appClient))); -}); \ No newline at end of file + await Promise.all( + forbiddenCases.map(async x => { + await x.action(appClient).then( + () => true, + ex => { + return expect(ex.message).to.contain('403'); + }, + ); + }), + ); + }).timeout(6000); + } +}); diff --git a/e2e/integration/spec/authoring-api/bulk-keys-upload.test.js b/e2e/integration/spec/authoring-api/bulk-keys-upload.test.js index 55892f187..02c3762ee 100644 --- a/e2e/integration/spec/authoring-api/bulk-keys-upload.test.js +++ b/e2e/integration/spec/authoring-api/bulk-keys-upload.test.js @@ -1,48 +1,51 @@ -const chai = require('chai'); -const expect = chai.expect; -chai.should(); -const {init:initClients} = require("../../utils/clients"); -const {pollUntil} = require("../../utils/utils"); +const { expect } = require('chai'); +const { init: initClients } = require('../../utils/clients'); +const { pollUntil } = require('../../utils/utils'); -describe('authoring api', () => { +describe('authoring api - bulk keys upload', () => { let clients; before(async () => { clients = await initClients(); }); - describe('/PUT /bulk-keys-upload', () => { - it('should accept a zip file and update rules', async () => { - const response = await clients.authoring.put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') - .attach('bulk', './spec/authoring-api/test-data/bulk1.zip') - response.status.should.eql(204); - await pollUntil(()=> clients.api.get('/api/v1/keys/test_key1?user.Country=country&user.ClientVersion=1.0.0'), - res=> expect(JSON.parse(res.body)).to.eql(true)) - }); + it('should accept a zip file and update rules', async () => { + const response = await clients.authoring + .put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') + .attach('bulk', './spec/authoring-api/test-data/bulk1.zip'); + response.status.should.eql(204); + await pollUntil( + () => clients.api.get('/api/v1/keys/test_key1?user.Country=country&user.ClientVersion=1.0.0'), + res => expect(JSON.parse(res.body)).to.eql(true), + ); + }); - it('should not accept an input without a zip file named bulk', async () => { - const response = await clients.authoring.put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') - response.status.should.eql(400); - response.text.should.eql('Required file is missing: bulk'); - }); + it('should not accept an input without a zip file named bulk', async () => { + const response = await clients.authoring.put( + '/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com', + ); + response.status.should.eql(400); + response.text.should.eql('Required file is missing: bulk'); + }); - it('should not accept a corrupted zip file', async () => { - const response = await clients.authoring.put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') - .attach('bulk', './spec/authoring-api/test-data/notZip.zip') - response.status.should.eql(400); - response.text.should.include('Zip is corrupted:'); - }); + it('should not accept a corrupted zip file', async () => { + const response = await clients.authoring + .put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') + .attach('bulk', './spec/authoring-api/test-data/notZip.zip'); + response.status.should.eql(400); + response.text.should.include('Zip is corrupted:'); + }); - it('should not accept a zip file with invalid structure', async () => { - const response = await clients.authoring.put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') - .attach('bulk', './spec/authoring-api/test-data/invalidStructure.zip') - response.status.should.eql(400); - }); + it('should not accept a zip file with invalid structure', async () => { + const response = await clients.authoring + .put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') + .attach('bulk', './spec/authoring-api/test-data/invalidStructure.zip'); + response.status.should.eql(400); + }); - it('should not accept a zip file with invalid rules', async () => { - const response = await clients.authoring.put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') - .attach('bulk', './spec/authoring-api/test-data/invalidRules.zip') - response.status.should.eql(500); - }); + it('should not accept a zip file with invalid rules', async () => { + const response = await clients.authoring + .put('/api/bulk-keys-upload?author.name=test&author.email=test@soluto.com') + .attach('bulk', './spec/authoring-api/test-data/invalidRules.zip'); + response.status.should.eql(500); }); }); - diff --git a/e2e/integration/spec/setup.js b/e2e/integration/spec/setup.js index 6476c6ff7..0067fd820 100644 --- a/e2e/integration/spec/setup.js +++ b/e2e/integration/spec/setup.js @@ -1,3 +1,6 @@ +const chai = require('chai'); +chai.should(); + const { init: initClients } = require('../utils/clients'); const { waitUntil } = require('../utils/utils'); diff --git a/e2e/integration/spec/tweek-api/key-aliases.test.js b/e2e/integration/spec/tweek-api/key-aliases.test.js new file mode 100644 index 000000000..ec776615d --- /dev/null +++ b/e2e/integration/spec/tweek-api/key-aliases.test.js @@ -0,0 +1,19 @@ +const { expect } = require('chai'); +const { init: initClients } = require('../../utils/clients'); + +const originalKey = 'integration_tests/some_key'; +const aliasKey = 'integration_tests/alias_key'; + +describe('tweek api - key aliases', () => { + let clients; + before(async () => { + clients = await initClients(); + }); + + it('should have the same value as the original key', async () => { + const original = await clients.api.get(`/api/v1/keys/${originalKey}`); + const alias = await clients.api.get(`/api/v1/keys/${aliasKey}`); + + expect(JSON.parse(original.body)).to.equal(JSON.parse(alias.body)); + }); +}); diff --git a/e2e/ui/spec/keys/add-key.js b/e2e/ui/spec/keys/add-key.js index ef10eef84..1c9add826 100644 --- a/e2e/ui/spec/keys/add-key.js +++ b/e2e/ui/spec/keys/add-key.js @@ -5,6 +5,7 @@ import { dataComp, dataField } from '../../utils/selector-utils'; import Key from '../../utils/Key'; import Rule from '../../utils/Rule'; import { login } from '../../utils/auth-utils'; +import KeysList from '../../utils/KeysList'; const timeout = 5000; @@ -38,6 +39,7 @@ describe('add key', () => { expect(Key.displayName).to.equal(keyToAddFullPath); expect(Key.hasChanges).to.be.false; + KeysList.assertInList(keyToAddFullPath); }); it('should succeed adding key by entering key path only', () => { @@ -56,5 +58,6 @@ describe('add key', () => { expect(Key.displayName).to.equal(keyWithDefaultsToAddFullPath); expect(Key.hasChanges).to.be.false; + KeysList.assertInList(keyWithDefaultsToAddFullPath); }); }); diff --git a/e2e/ui/spec/keys/delete-key.js b/e2e/ui/spec/keys/delete-key.js index a5573bba7..7826e7c8d 100644 --- a/e2e/ui/spec/keys/delete-key.js +++ b/e2e/ui/spec/keys/delete-key.js @@ -3,6 +3,7 @@ import { expect } from 'chai'; import Key from '../../utils/Key'; import Alert from '../../utils/Alert'; +import KeysList from '../../utils/KeysList'; import { dataComp } from '../../utils/selector-utils'; import authoringClient from '../../clients/authoring-client'; import { login } from '../../utils/auth-utils'; @@ -15,6 +16,8 @@ const deleteKey = dataComp('delete-key'); const keyMessage = dataComp('key-message'); const assertKeyDeleted = keyName => { + KeysList.assertInList(keyName, true); + authoringClient.waitForKeyToBeDeleted(keyName); Key.open(keyName, false); @@ -36,6 +39,8 @@ describe('delete key', () => { browser.waitForVisible(archiveKey, timeout, true); browser.waitForVisible(unarchiveKey, timeout); browser.waitForVisible(deleteKey, timeout); + + KeysList.assertInList(keyName, true); }); }); @@ -51,6 +56,8 @@ describe('delete key', () => { browser.waitForVisible(archiveKey, timeout); browser.waitForVisible(unarchiveKey, timeout, true); browser.waitForVisible(deleteKey, timeout, true); + + KeysList.assertInList(keyName); }); }); @@ -83,8 +90,9 @@ describe('delete key', () => { expect(Key.exists).to.be.true; }); - it.only('should succeed deleting key', () => { + it('should succeed deleting key', () => { const keyName = 'behavior_tests/delete_key/delete/accepted'; + const aliasKey = 'behavior_tests/delete_key/delete/alias'; Key.open(keyName); browser.click(deleteKey); @@ -94,6 +102,7 @@ describe('delete key', () => { expect(browser.getUrl(), 'should move to keys page url').to.endWith('/keys'); assertKeyDeleted(keyName); + assertKeyDeleted(aliasKey); }); }); }); diff --git a/e2e/ui/spec/keys/dependent-keys.js b/e2e/ui/spec/keys/dependent-keys.js index add126b62..9598e301c 100644 --- a/e2e/ui/spec/keys/dependent-keys.js +++ b/e2e/ui/spec/keys/dependent-keys.js @@ -32,16 +32,16 @@ describe('dependent keys', () => { it('should display dependency relations between keys', () => { const dependsOn = 'behavior_tests/dependent_keys/display/depends_on'; + const dependsOnAlias = 'behavior_tests/dependent_keys/display/depends_on_alias'; const usedBy = 'behavior_tests/dependent_keys/display/used_by'; // Verify depends on - Key.open(dependsOn); - browser.clickWhenVisible(dataComp('depends-on-toggle'), timeout); + Key.open(dependsOn).toggle('depends-on'); browser.waitForVisible(`${dataComp('depends-on')} a[href="/keys/${usedBy}"]`); // Verify used by - Key.open(usedBy); - browser.clickWhenVisible(dataComp('used-by-toggle'), timeout); + Key.open(usedBy).toggle('used-by'); browser.waitForVisible(`${dataComp('used-by')} a[href="/keys/${dependsOn}"]`); + browser.waitForVisible(`${dataComp('used-by')} a[href="/keys/${dependsOnAlias}"]`); }); }); diff --git a/e2e/ui/spec/keys/key-aliases.js b/e2e/ui/spec/keys/key-aliases.js new file mode 100644 index 000000000..923130f33 --- /dev/null +++ b/e2e/ui/spec/keys/key-aliases.js @@ -0,0 +1,60 @@ +/* global describe, before, beforeEach, after, afterEach, it, browser */ + +import { expect } from 'chai'; +import Key from '../../utils/Key'; +import KeysList from '../../utils/KeysList'; +import Alert from '../../utils/Alert'; +import { dataComp, attributeSelector } from '../../utils/selector-utils'; +import { login } from '../../utils/auth-utils'; +import authoringClient from '../../clients/authoring-client'; + +const timeout = 5000; +const addAliasButton = dataComp('add-alias'); +const aliasContainer = alias => + `${dataComp('aliases')} ${attributeSelector('data-dependency', alias)}`; +const deleteAliasButton = alias => `${aliasContainer(alias)} ${dataComp('delete-alias')}`; + +describe('key aliases', () => { + const originalKeyPath = 'behavior_tests/key_aliases/regular_key'; + const aliasKeyPath = 'behavior_tests/key_aliases/alias_key'; + const aliasToAliasKeyPath = 'behavior_tests/key_aliases/alias_to_alias'; + const newAliasKeyPath = 'behavior_tests/key_aliases/new_alias'; + const deleteAliasKeyPath = 'behavior_tests/key_aliases/delete_alias'; + + before(login); + + it('should add alias', () => { + Key.open(originalKeyPath); + + browser.clickWhenVisible(addAliasButton, timeout); + Alert.waitFor('ok'); + Key.setName(newAliasKeyPath); + Alert.ok(); + + Key.toggle('aliases'); + browser.waitForVisible(aliasContainer(newAliasKeyPath)); + KeysList.assertInList(newAliasKeyPath); + }); + + it('should delete alias', () => { + Key.open(deleteAliasKeyPath); + Key.toggle('aliases'); + + browser.clickWhenVisible(deleteAliasButton(deleteAliasKeyPath)); + Alert.ok(); + browser.waitForVisible(aliasContainer(deleteAliasKeyPath), true); + KeysList.assertInList(deleteAliasKeyPath, true); + authoringClient.waitForKeyToBeDeleted(deleteAliasKeyPath); + }); + + it('should redirect to key when navigating to alias', () => { + KeysList.navigate(aliasKeyPath); + + browser.waitUntil(() => Key.isCurrent(originalKeyPath), timeout); + + Key.toggle('aliases'); + + browser.waitForVisible(aliasContainer(aliasKeyPath)); + browser.waitForVisible(aliasContainer(aliasToAliasKeyPath)); + }); +}); diff --git a/e2e/ui/spec/keys/keys-list.js b/e2e/ui/spec/keys/keys-list.js index 4630a77f7..98d0f281b 100644 --- a/e2e/ui/spec/keys/keys-list.js +++ b/e2e/ui/spec/keys/keys-list.js @@ -2,6 +2,7 @@ import { expect } from 'chai'; import Key from '../../utils/Key'; +import KeysList from '../../utils/KeysList'; import { attributeSelector, dataComp } from '../../utils/selector-utils'; import { login } from '../../utils/auth-utils'; @@ -21,13 +22,13 @@ describe('keys list and filter', () => { }); it('should be able to navigate to key by folders', () => { - Key.navigate(greenAppleKeyFullPath); + KeysList.navigate(greenAppleKeyFullPath); expect(Key.isCurrent(greenAppleKeyFullPath)).to.be.true; }); it('should display matching keys when filtering', () => { - Key.search('apple'); + KeysList.search('apple'); browser.waitForVisible(keyLink(greenAppleKeyFullPath), 2000); browser.waitForVisible(keyLink(redAppleKeyFullPath), 2000); diff --git a/e2e/ui/spec/keys/routing.js b/e2e/ui/spec/keys/routing.js index 14f6f018b..71170fd4a 100644 --- a/e2e/ui/spec/keys/routing.js +++ b/e2e/ui/spec/keys/routing.js @@ -1,6 +1,7 @@ /* global describe, before, after, beforeEach, it, browser */ import Key from '../../utils/Key'; +import KeysList from '../../utils/KeysList'; import Rule from '../../utils/Rule'; import { login } from '../../utils/auth-utils'; @@ -23,7 +24,7 @@ describe('navigating from key with changes', () => { Rule.add(); browser.waitUntil(() => Key.hasChanges, timeout); - Key.navigate(keyName); + KeysList.navigate(keyName); browser.waitForAlert(timeout, 'should show confirm message'); browser.alertAccept(); diff --git a/e2e/ui/utils/Key.js b/e2e/ui/utils/Key.js index 14840978a..d9f8991df 100644 --- a/e2e/ui/utils/Key.js +++ b/e2e/ui/utils/Key.js @@ -1,7 +1,6 @@ /* global browser */ import assert from 'assert'; -import R from 'ramda'; import { expect } from 'chai'; import { dataComp, dataField, attributeSelector } from './selector-utils'; @@ -20,18 +19,8 @@ const rulesEditor = dataComp('key-rules-editor'); const tabHeader = attributeSelector('data-tab-header'); const sourceTab = `${rulesEditor} ${tabHeader('source')}`; const rulesTab = `${rulesEditor} ${tabHeader('rules')}`; -const searchKeyInput = dataComp('search-key-input'); -const directoryTreeView = dataComp('directory-tree-view'); -const treeItem = (attribute, value) => - `${directoryTreeView} ${attributeSelector(attribute, value)}`; - -const extractFolders = R.pipe( - R.split('/'), - R.dropLast(1), - R.mapAccum((acc, value) => R.repeat(acc ? `${acc}/${value}` : value, 2), null), - R.prop(1), -); +const toggleButton = comp => `${dataComp(comp)} ${dataComp('expander-toggle')}`; class Key { BLANK_KEY_NAME = '_blank'; @@ -50,20 +39,6 @@ class Key { return this; } - navigate(keyName) { - const keyFolders = extractFolders(keyName); - - keyFolders.forEach( - folder => browser.clickWhenVisible(treeItem('data-folder-name', folder)), - timeout, - ); - - const keyLinkSelector = treeItem('href', `/keys/${keyName}`); - browser.clickWhenVisible(keyLinkSelector, timeout); - - return this; - } - add() { this.open(); browser.click(dataComp('add-new-key')); @@ -80,12 +55,6 @@ class Key { return this.waitToLoad(); } - search(filter) { - browser.waitForVisible(searchKeyInput, timeout); - browser.setValue(searchKeyInput, filter); - return this; - } - get hasChanges() { return browser.getAttribute(saveChangesButton, 'data-state-has-changes') === 'true'; } @@ -189,6 +158,11 @@ class Key { browser.click(dataComp('save-jpad-text')); return this; } + + toggle(section) { + browser.clickWhenVisible(toggleButton(section), timeout); + return this; + } } export default new Key(); diff --git a/e2e/ui/utils/KeysList.js b/e2e/ui/utils/KeysList.js new file mode 100644 index 000000000..dd1411309 --- /dev/null +++ b/e2e/ui/utils/KeysList.js @@ -0,0 +1,50 @@ +import { attributeSelector, dataComp } from './selector-utils'; +import * as R from 'ramda'; + +const timeout = 5000; + +const searchKeyInput = dataComp('search-key-input'); +const directoryTreeView = dataComp('directory-tree-view'); +const treeItem = (attribute, value) => + `${directoryTreeView} ${attributeSelector(attribute, value)}`; + +const extractFolders = R.pipe( + R.split('/'), + R.dropLast(1), + R.mapAccum((acc, value) => R.repeat(acc ? `${acc}/${value}` : value, 2), null), + R.prop(1), +); + +class KeysList { + navigate(keyName) { + const keyFolders = extractFolders(keyName); + + keyFolders.forEach(folder => + browser.clickWhenVisible(treeItem('data-folder-name', folder), timeout), + ); + + const keyLinkSelector = treeItem('href', `/keys/${keyName}`); + browser.clickWhenVisible(keyLinkSelector, timeout); + + return this; + } + + assertInList(keyName, reverse) { + const keyFolders = extractFolders(keyName); + + for (const folder of keyFolders) { + browser.clickIfVisible(treeItem('data-folder-name', folder), 1000, reverse); + } + + const keyLinkSelector = treeItem('href', `/keys/${keyName}`); + browser.waitForVisible(keyLinkSelector, 1000, reverse); + } + + search(filter) { + browser.waitForVisible(searchKeyInput, timeout); + browser.setValue(searchKeyInput, filter); + return this; + } +} + +export default new KeysList(); diff --git a/e2e/ui/utils/browser-extension-commands.js b/e2e/ui/utils/browser-extension-commands.js index e92dbedec..e5c736d27 100644 --- a/e2e/ui/utils/browser-extension-commands.js +++ b/e2e/ui/utils/browser-extension-commands.js @@ -5,11 +5,13 @@ module.exports = function(browser) { return this.waitUntil(() => this.alertText(), timeout, timeoutMsg, interval); }); - browser.addCommand('clickIfVisible', function(selector, timeout) { + browser.addCommand('clickIfVisible', function(selector, timeout, reverse) { try { - this.waitForVisible(selector, timeout); + this.waitForVisible(selector, timeout, reverse); this.pause(50); - this.click(selector); + if (!reverse) { + this.click(selector); + } } catch (_) {} }); diff --git a/e2e/ui/yarn.lock b/e2e/ui/yarn.lock index 813381e2b..e51bd4ed0 100644 --- a/e2e/ui/yarn.lock +++ b/e2e/ui/yarn.lock @@ -287,7 +287,7 @@ babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" -babel-eslint@^8.0.2: +babel-eslint@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.3.tgz#f29ecf02336be438195325cd47c468da81ee4e98" dependencies: @@ -2715,11 +2715,11 @@ rx@2.3.24: version "2.3.24" resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" -rxjs@^5.5.3: - version "5.5.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.3.tgz#b62227e74b84f4e77bdf440e50b5ee01a1bc7dcd" +rxjs@^5.5.4: + version "5.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.5.tgz#e164f11d38eaf29f56f08c3447f74ff02dd84e97" dependencies: - symbol-observable "^1.0.1" + symbol-observable "1.0.1" safe-buffer@^5.0.1: version "5.0.1" @@ -2947,9 +2947,9 @@ supports-color@~5.0.0: dependencies: has-flag "^2.0.0" -symbol-observable@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" tar-pack@^3.4.0: version "3.4.0" diff --git a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/HiddenKeysTests.cs b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/HiddenKeysTests.cs index a0d3c5b56..42ca9168d 100644 --- a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/HiddenKeysTests.cs +++ b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/HiddenKeysTests.cs @@ -21,7 +21,7 @@ public HiddenKeysTests(ITestOutputHelper output) public async Task GetScanFolder_VisibleFolder_ShouldReturnVisibleKeys() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/not_hidden/_", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/not_hidden/_", new Dictionary()); // Assert Assert.Equal(JTokenType.Object, response.Type); @@ -33,7 +33,7 @@ public async Task GetScanFolder_VisibleFolder_ShouldReturnVisibleKeys() public async Task GetScanFolder_HiddenFolder_ShouldReturnVisibleKeys() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/not_hidden/@hidden/_", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/not_hidden/@hidden/_", new Dictionary()); // Assert Assert.Equal(JTokenType.Object, response.Type); @@ -45,7 +45,7 @@ public async Task GetScanFolder_HiddenFolder_ShouldReturnVisibleKeys() public async Task GetScanFolder_IncludeHiddenFolder_ShouldReturnHiddenFolder() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/not_hidden/_", new List> + var response = await mTweekApi.GetConfigurations("smoke_tests/not_hidden/_", new List> { new KeyValuePair("$include", "_"), new KeyValuePair("$include", "@hidden/_") @@ -61,7 +61,7 @@ public async Task GetScanFolder_IncludeHiddenFolder_ShouldReturnHiddenFolder() public async Task GetKey_HiddenKey_ShouldReturnKey() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/not_hidden/@some_hidden_key", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/not_hidden/@some_hidden_key", new Dictionary()); // Assert Assert.Equal(JTokenType.String, response.Type); diff --git a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/KeyPathsTests.cs b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/KeyPathsTests.cs index c73aa29c0..b1557576a 100644 --- a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/KeyPathsTests.cs +++ b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/KeyPathsTests.cs @@ -20,7 +20,7 @@ public KeyPathsTests(ITestOutputHelper output) public async Task GetSingleKey_KeyExists_ShouldReturnKeyValue() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/key_path/key1", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/key_path/key1", new Dictionary()); // Assert Assert.Equal(JTokenType.String, response.Type); @@ -31,7 +31,7 @@ public async Task GetSingleKey_KeyExists_ShouldReturnKeyValue() public async Task GetSingleKey_KeyDoesntExists_ShouldReturnNull() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/key_path/nonexisting-key", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/key_path/nonexisting-key", new Dictionary()); // Assert Assert.Equal(JTokenType.Null, response.Type); @@ -41,7 +41,7 @@ public async Task GetSingleKey_KeyDoesntExists_ShouldReturnNull() public async Task GetKeyTree_KeysExistsInPath_ShouldReturnObjectWithValueForEachKey() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/key_path/_", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/key_path/_", new Dictionary()); // Assert Assert.Equal(JTokenType.Object, response.Type); @@ -56,14 +56,14 @@ public async Task GetMultipleKeys_KeysExists_ShouldReturnObjectWithValueForEachK // Act var response = await mTweekApi.GetConfigurations("_", new List> { - new KeyValuePair("$include", "@smoke_tests/key_path/key1"), - new KeyValuePair("$include", "@smoke_tests/key_path/key2") + new KeyValuePair("$include", "smoke_tests/key_path/key1"), + new KeyValuePair("$include", "smoke_tests/key_path/key2") }); // Assert Assert.Equal(JTokenType.Object, response.Type); - Assert.Equal("test", response.Value("@smoke_tests").Value("key_path").Value("key1")); - Assert.Equal("test", response.Value("@smoke_tests").Value("key_path").Value("key2")); + Assert.Equal("test", response.Value("smoke_tests").Value("key_path").Value("key1")); + Assert.Equal("test", response.Value("smoke_tests").Value("key_path").Value("key2")); } [Fact(DisplayName = "Requesting multiple keys using $include should return an object with the values for all the keys with full path")] @@ -72,21 +72,21 @@ public async Task GetMultipleKeys_WithScan_ShouldReturnObjectWithValueForEachKey // Act var response = await mTweekApi.GetConfigurations("_", new List> { - new KeyValuePair("$include", "@smoke_tests/key_path/key1"), - new KeyValuePair("$include", "@smoke_tests/key_path/_") + new KeyValuePair("$include", "smoke_tests/key_path/key1"), + new KeyValuePair("$include", "smoke_tests/key_path/_") }); // Assert Assert.Equal(JTokenType.Object, response.Type); - Assert.Equal("test", response.Value("@smoke_tests").Value("key_path").Value("key1")); - Assert.Equal("test", response.Value("@smoke_tests").Value("key_path").Value("key2")); + Assert.Equal("test", response.Value("smoke_tests").Value("key_path").Value("key1")); + Assert.Equal("test", response.Value("smoke_tests").Value("key_path").Value("key2")); } [Fact(DisplayName = "Requesting multiple keys with $include should be relative to the path")] public async Task GetMultipleKeys_WithScanRoot_ResultsShouldBeRelativeToThePath() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/_", new List> + var response = await mTweekApi.GetConfigurations("smoke_tests/_", new List> { new KeyValuePair("$include", "key_path/key1"), new KeyValuePair("$include", "key_path/_") @@ -102,7 +102,7 @@ public async Task GetMultipleKeys_WithScanRoot_ResultsShouldBeRelativeToThePath( public async Task GetKeyTree_PathDoesntExist_ShouldReturnEmptyObject() { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/key_path/nonexisting-key-path/_", new Dictionary()); + var response = await mTweekApi.GetConfigurations("smoke_tests/key_path/nonexisting-key-path/_", new Dictionary()); // Assert Assert.Equal(JTokenType.Object, response.Type); diff --git a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/IdentityBasedTestsContextProvider.cs b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/IdentityBasedTestsContextProvider.cs index 12062abf0..8610afa76 100644 --- a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/IdentityBasedTestsContextProvider.cs +++ b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/IdentityBasedTestsContextProvider.cs @@ -12,7 +12,7 @@ public static IEnumerable IDENTITY_TEST_CONTEXTS() new TestContext { TestName = "Get key based on identity, should reutrn matching value", - KeyName = "@smoke_tests/identity_context/color", + KeyName = "smoke_tests/identity_context/color", ExpectedValue = "yellow", Context = new Dictionary { @@ -24,7 +24,7 @@ public static IEnumerable IDENTITY_TEST_CONTEXTS() new TestContext { TestName = "Get key based on identity with field override, should return matching value", - KeyName = "@smoke_tests/identity_context/color", + KeyName = "smoke_tests/identity_context/color", ExpectedValue = "green", Context = new Dictionary { @@ -37,7 +37,7 @@ public static IEnumerable IDENTITY_TEST_CONTEXTS() new TestContext { TestName = "Get key based on unknown identity, should return default value", - KeyName = "@smoke_tests/identity_context/color", + KeyName = "smoke_tests/identity_context/color", ExpectedValue = "unknown", Context = new Dictionary { diff --git a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/RulesBasedTestsContextProvider.cs b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/RulesBasedTestsContextProvider.cs index faa7f11bc..2a0313799 100644 --- a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/RulesBasedTestsContextProvider.cs +++ b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/Models/RulesBasedTestsContextProvider.cs @@ -27,7 +27,7 @@ public static IEnumerable COMPARISON_OPERATORS_TEST_CONTEXTS() new TestContext { TestName = COMPARISON_OPERATORS_TEST_NAME_4, - KeyName = "@smoke_tests/rule_based_keys/comparison", + KeyName = "smoke_tests/rule_based_keys/comparison", ExpectedValue = "value4", Context = new Dictionary { @@ -39,7 +39,7 @@ public static IEnumerable COMPARISON_OPERATORS_TEST_CONTEXTS() new TestContext { TestName = COMPARISON_OPERATORS_TEST_NAME_3, - KeyName = "@smoke_tests/rule_based_keys/comparison", + KeyName = "smoke_tests/rule_based_keys/comparison", ExpectedValue = "value3", Context = new Dictionary { @@ -51,7 +51,7 @@ public static IEnumerable COMPARISON_OPERATORS_TEST_CONTEXTS() new TestContext { TestName = COMPARISON_OPERATORS_TEST_NAME_2, - KeyName = "@smoke_tests/rule_based_keys/comparison", + KeyName = "smoke_tests/rule_based_keys/comparison", ExpectedValue = "value2", Context = new Dictionary { @@ -63,7 +63,7 @@ public static IEnumerable COMPARISON_OPERATORS_TEST_CONTEXTS() new TestContext { TestName = COMPARISON_OPERATORS_TEST_NAME_1, - KeyName = "@smoke_tests/rule_based_keys/comparison", + KeyName = "smoke_tests/rule_based_keys/comparison", ExpectedValue = "value1" }}; } @@ -74,7 +74,7 @@ public static IEnumerable IN_OPERATOR_TEST_CONTEXTS() new TestContext { TestName = IN_OPERATOR_TEST_NAME_4, - KeyName = "@smoke_tests/rule_based_keys/in", + KeyName = "smoke_tests/rule_based_keys/in", ExpectedValue = "value4", Context = new Dictionary { @@ -86,7 +86,7 @@ public static IEnumerable IN_OPERATOR_TEST_CONTEXTS() new TestContext { TestName = IN_OPERATOR_TEST_NAME_3, - KeyName = "@smoke_tests/rule_based_keys/in", + KeyName = "smoke_tests/rule_based_keys/in", ExpectedValue = "value3", Context = new Dictionary { @@ -98,7 +98,7 @@ public static IEnumerable IN_OPERATOR_TEST_CONTEXTS() new TestContext { TestName = IN_OPERATOR_TEST_NAME_2, - KeyName = "@smoke_tests/rule_based_keys/in", + KeyName = "smoke_tests/rule_based_keys/in", ExpectedValue = "value2", Context = new Dictionary { @@ -110,7 +110,7 @@ public static IEnumerable IN_OPERATOR_TEST_CONTEXTS() new TestContext { TestName = IN_OPERATOR_TEST_NAME_1, - KeyName = "@smoke_tests/rule_based_keys/in", + KeyName = "smoke_tests/rule_based_keys/in", ExpectedValue = "value1" }}; } @@ -121,7 +121,7 @@ public static IEnumerable MULTI_CONDITIONS_TEST_CONTEXTS() new TestContext { TestName = MULTI_CONDITONS_TEST_NAME_4, - KeyName = "@smoke_tests/rule_based_keys/multi_conditions", + KeyName = "smoke_tests/rule_based_keys/multi_conditions", ExpectedValue = "value4", Context = new Dictionary { @@ -141,7 +141,7 @@ public static IEnumerable MULTI_CONDITIONS_TEST_CONTEXTS() new TestContext { TestName = MULTI_CONDITONS_TEST_NAME_3, - KeyName = "@smoke_tests/rule_based_keys/multi_conditions", + KeyName = "smoke_tests/rule_based_keys/multi_conditions", ExpectedValue = "value3", Context = new Dictionary { @@ -155,7 +155,7 @@ public static IEnumerable MULTI_CONDITIONS_TEST_CONTEXTS() new TestContext { TestName = MULTI_CONDITONS_TEST_NAME_2, - KeyName = "@smoke_tests/rule_based_keys/multi_conditions", + KeyName = "smoke_tests/rule_based_keys/multi_conditions", ExpectedValue = "value2", Context = new Dictionary { @@ -168,7 +168,7 @@ public static IEnumerable MULTI_CONDITIONS_TEST_CONTEXTS() new TestContext { TestName = MULTI_CONDITONS_TEST_NAME_1, - KeyName = "@smoke_tests/rule_based_keys/multi_conditions", + KeyName = "smoke_tests/rule_based_keys/multi_conditions", ExpectedValue = "value1" }}; } diff --git a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/RuleBasedKeysTests.cs b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/RuleBasedKeysTests.cs index fedc97259..f84fc9234 100644 --- a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/RuleBasedKeysTests.cs +++ b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/RuleBasedKeysTests.cs @@ -25,7 +25,7 @@ public RuleBasedKeysTests(ITestOutputHelper output) public async Task GetSingleKey_BySimpleRules_ShouldReturnMatchingKeyValue(string osType, string expectedResult) { // Act - var response = await mTweekApi.GetConfigurations("@smoke_tests/rule_based_keys/simple", new Dictionary { { "device.DeviceOsType", osType } }); + var response = await mTweekApi.GetConfigurations("smoke_tests/rule_based_keys/simple", new Dictionary { { "device.DeviceOsType", osType } }); // Assert Assert.Equal(JTokenType.String, response.Type); diff --git a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/ValueDistributionTests.cs b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/ValueDistributionTests.cs index 7aefc859d..555ad5f85 100644 --- a/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/ValueDistributionTests.cs +++ b/services/api/Tweek.ApiService.SmokeTests/GetConfigurations/ValueDistributionTests.cs @@ -36,7 +36,7 @@ public async Task GetKeyWithBernoulliValueDistribution_SeveralRequestsFromDiffer // Act var keyRequests = Enumerable.Range(0, numberOfAttempts) - .Select(async i => await mTweekApi.GetConfigurations("@smoke_tests/value_distribution/bernoulli", new Dictionary { { "device", Guid.NewGuid().ToString() } })); + .Select(async i => await mTweekApi.GetConfigurations("smoke_tests/value_distribution/bernoulli", new Dictionary { { "device", Guid.NewGuid().ToString() } })); var results = await Task.WhenAll(keyRequests); var returnedValues = results.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()).ToList(); @@ -60,7 +60,7 @@ public async Task GetKeyWithMultiVariantsValues_SeveralRequestsFromDifferentIden // Act var keyRequests = Enumerable.Range(0, numberOfAttempts) - .Select(async i => await mTweekApi.GetConfigurations("@smoke_tests/value_distribution/weighted_normalized", new Dictionary { { "device", Guid.NewGuid().ToString() } })); + .Select(async i => await mTweekApi.GetConfigurations("smoke_tests/value_distribution/weighted_normalized", new Dictionary { { "device", Guid.NewGuid().ToString() } })); var results = await Task.WhenAll(keyRequests); var returnedValues = results.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()).ToList(); diff --git a/services/api/Tweek.ApiService/Startup.cs b/services/api/Tweek.ApiService/Startup.cs index 27e0c234e..2a191085d 100644 --- a/services/api/Tweek.ApiService/Startup.cs +++ b/services/api/Tweek.ApiService/Startup.cs @@ -199,7 +199,8 @@ private static GetRuleParser CreateParserResolver() var dict = new Dictionary(StringComparer.OrdinalIgnoreCase){ ["jpad"] = jpadParser, - ["const"] = Engine.Core.Rules.Utils.ConstValueParser + ["const"] = Engine.Core.Rules.Utils.ConstValueParser, + ["alias"] = Engine.Core.Rules.Utils.KeyAliasParser, }; return x=>dict[x]; diff --git a/services/api/Tweek.ApiService/Tweek.ApiService.csproj b/services/api/Tweek.ApiService/Tweek.ApiService.csproj index 1a20b00d3..8516204c6 100644 --- a/services/api/Tweek.ApiService/Tweek.ApiService.csproj +++ b/services/api/Tweek.ApiService/Tweek.ApiService.csproj @@ -1,7 +1,7 @@  netcoreapp2.0 - 0.4.1 + 0.5.0 ..\..\..\deployments\docker-compose.dcproj true 1591, 1701, 1702, 1998 diff --git a/services/authoring/package.json b/services/authoring/package.json index d25d40a76..2db46c752 100644 --- a/services/authoring/package.json +++ b/services/authoring/package.json @@ -1,6 +1,6 @@ { "name": "tweek-authoring", - "version": "0.2.4", + "version": "0.3.0", "main": "src/server.js", "repository": "Soluto/tweek", "author": "Soluto", diff --git a/services/authoring/src/repositories/keys-repository.ts b/services/authoring/src/repositories/keys-repository.ts index df2945546..a397f5482 100644 --- a/services/authoring/src/repositories/keys-repository.ts +++ b/services/authoring/src/repositories/keys-repository.ts @@ -1,6 +1,6 @@ import path = require('path'); -import Transactor from "../utils/transactor"; -import GitRepository from "./git-repository"; +import Transactor from '../utils/transactor'; +import GitRepository from './git-repository'; function generateEmptyManifest(keyPath) { return { @@ -24,7 +24,9 @@ function generateEmptyManifest(keyPath) { function getNewJpadFormatSourceIfNeeded(originalJpadSource) { const parsedJpad = JSON.parse(originalJpadSource); - if (!Array.isArray(parsedJpad)) return originalJpadSource; + if (!Array.isArray(parsedJpad)) { + return originalJpadSource; + } return JSON.stringify({ partitions: [], @@ -33,15 +35,6 @@ function getNewJpadFormatSourceIfNeeded(originalJpadSource) { }); } -//todo remove legacy -function getLegacyPathForManifest(keyName) { - return `meta/${keyName}.json`; -} - -function getLegacyPathForSourceFile(manifest) { - return `rules/${manifest.key_path}.${manifest.implementation.format}`; -} - function getPathForManifest(keyName) { return `manifests/${keyName}.json`; } @@ -64,12 +57,7 @@ async function updateKey(gitRepo, keyPath, manifest, fileImplementation) { } async function getFileImplementation(manifest, repo, revision) { - let source: any; - try { - source = await repo.readFile(getPathForSourceFile(manifest), { revision }); - } catch (err) { - source = await repo.readFile(getLegacyPathForSourceFile(manifest), { revision }); - } + let source = await repo.readFile(getPathForSourceFile(manifest), { revision }); if (manifest.implementation.format === 'jpad') { source = getNewJpadFormatSourceIfNeeded(source); @@ -89,14 +77,8 @@ async function getRevisionHistory(manifest, repo, config) { async function getManifestFile(keyPath: string, gitRepo, revision?: string) { try { - let fileContent; - try { - const pathForManifest = getPathForManifest(keyPath); - fileContent = await gitRepo.readFile(pathForManifest, { revision }); - } catch (exp) { - const pathForManifest = getLegacyPathForManifest(keyPath); - fileContent = await gitRepo.readFile(pathForManifest, { revision }); - } + const pathForManifest = getPathForManifest(keyPath); + const fileContent = await gitRepo.readFile(pathForManifest, { revision }); return JSON.parse(fileContent); } catch (exp) { return generateEmptyManifest(keyPath); @@ -119,7 +101,7 @@ export default class KeysRepository { return this._gitTransactionManager.with(async (gitRepo) => { const normalizedPrefix = `${path.normalize(`manifests/${prefix}/.`)}`.replace(/\\/g, '/'); const files = await gitRepo.listFiles(normalizedPrefix); - const manifestFiles = files.map(path => `${normalizedPrefix}/${path}`); + const manifestFiles = files.map(keyPath => `${normalizedPrefix}/${keyPath}`); const manifests = await Promise.all( manifestFiles.map(pathForManifest => gitRepo.readFile(pathForManifest)), ); @@ -133,9 +115,9 @@ export default class KeysRepository { return { manifest, implementation: - manifest.implementation.type === 'file' - ? await getFileImplementation(manifest, gitRepo, revision) - : undefined, + manifest.implementation.type === 'file' + ? await getFileImplementation(manifest, gitRepo, revision) + : undefined, }; }); } @@ -163,7 +145,7 @@ export default class KeysRepository { updateBulkKeys(files, author, commitMessage = 'Bulk update through API') { return this._gitTransactionManager.write(async (gitRepo) => { - for (let file of files) { + for (const file of files) { const content = await file.read(); await gitRepo.updateFile(file.name, content); } @@ -171,15 +153,16 @@ export default class KeysRepository { }); } - deleteKey(keyPath, author) { + deleteKeys(keys: string[], author) { return this._gitTransactionManager.write(async (gitRepo) => { - const manifest = await getManifestFile(keyPath, gitRepo); - await gitRepo.deleteFile(getPathForManifest(keyPath)); - if (manifest.implementation.type === 'file') { - await gitRepo.deleteFile(getPathForSourceFile(manifest)); + for (const keyPath of keys) { + const manifest = await getManifestFile(keyPath, gitRepo); + await gitRepo.deleteFile(getPathForManifest(keyPath)); + if (manifest.implementation.type === 'file') { + await gitRepo.deleteFile(getPathForSourceFile(manifest)); + } } - - await gitRepo.commitAndPush(`Editor - deleting ${keyPath}`, author); + await gitRepo.commitAndPush(`Editor - deleting keys: ${keys.join(', ')}`, author); }); } diff --git a/services/authoring/src/routes/keys.ts b/services/authoring/src/routes/keys.ts index 3b0d68f4c..a0db52a8d 100644 --- a/services/authoring/src/routes/keys.ts +++ b/services/authoring/src/routes/keys.ts @@ -58,8 +58,14 @@ export class KeysController { @Authorize({ permission: PERMISSIONS.KEYS_WRITE }) @DELETE @Path('/key') - async deleteKey( @QueryParam('keyPath') keyPath: string, @QueryParam('author.name') name: string, @QueryParam('author.email') email: string): Promise { - await this.keysRepository.deleteKey(keyPath, { name, email }); + async deleteKey( @QueryParam('keyPath') keyPath: string, @QueryParam('author.name') name: string, @QueryParam('author.email') email: string, additionalKeys?: string[]): Promise { + let keysToDelete = [keyPath]; + if (additionalKeys && Array.isArray(additionalKeys)) { + keysToDelete = keysToDelete.concat(additionalKeys); + } + + console.log('keys to delete', keysToDelete); + await this.keysRepository.deleteKeys(keysToDelete, { name, email }); return 'OK'; } @@ -91,8 +97,7 @@ export class KeysController { @Path('/manifest') async getManifest( @QueryParam('keyPath') keyPath: string, @QueryParam('revision') revision?: string): Promise { try { - const manifest = await this.keysRepository.getKeyManifest(keyPath, { revision }); - return manifest; + return await this.keysRepository.getKeyManifest(keyPath, { revision }); } catch (exp) { throw new Errors.NotFoundError(); } diff --git a/services/authoring/src/routes/schema.ts b/services/authoring/src/routes/schema.ts index 57374aad4..0b6a42d87 100644 --- a/services/authoring/src/routes/schema.ts +++ b/services/authoring/src/routes/schema.ts @@ -39,7 +39,7 @@ export class SchemaController { @Path('/schemas/:identityType') async deleteIdentity( @PathParam('identityType') identityType: string, @QueryParam('author.name') name: string, @QueryParam('author.email') email: string): Promise { const keyPath = schemaPrefix + identityType; - await this.keysRepository.deleteKey(keyPath, { name, email }); + await this.keysRepository.deleteKeys([keyPath], { name, email }); return 'OK'; } diff --git a/services/authoring/src/search-index/index.ts b/services/authoring/src/search-index/index.ts index c89aa4455..8e9b4e185 100644 --- a/services/authoring/src/search-index/index.ts +++ b/services/authoring/src/search-index/index.ts @@ -29,15 +29,34 @@ async function refreshIndex(repoDir) { return index; } -const indexDependencies = R.pipe( - R.filter((manifest: any) => !!manifest.dependencies), - R.chain(R.pipe( - R.props(['key_path', 'dependencies']), - ([keyPath, dependencies]: [any, any]) => dependencies.map(dependency => ({ dependency, keyPath })), - )), - R.groupBy(R.prop('dependency')), - R.map(R.map(R.prop('keyPath'))), -); +function createDependencyIndexes(manifests) { + const aliases = manifests.filter((manifest: any) => manifest.implementation.type === 'alias') + .reduce((acc, manifest) => ({ ...acc, [manifest.key_path]: manifest.implementation.key }), {}); + + const getKey = key => key in aliases ? getKey(aliases[key]) : key; + + const createAliasIndex = R.pipe( + R.map(getKey), + R.invert, + ); + + const aliasIndex = createAliasIndex(aliases); + + const indexDependencies = R.pipe( + R.filter((manifest: any) => !!manifest.dependencies && manifest.implementation.type !== 'alias'), + R.chain(R.pipe( + R.props(['key_path', 'dependencies']), + ([keyPath, dependencies]: [any, any]) => dependencies.map(dependency => ({ dependency: getKey(dependency), keyPath })), + )), + R.groupBy(R.prop('dependency')), + R.map(R.map(R.prop('keyPath'))), + R.map(R.uniq), + ); + + const dependencyIndex = indexDependencies(manifests); + + return { aliasIndex, dependencyIndex }; +} export default { get indexPromise() { @@ -50,12 +69,12 @@ export default { return index; }, dependents(key) { - return dependentsPromise.then(x => x[key] || []); + return dependentsPromise.then(({ aliasIndex, dependencyIndex }) => ({ usedBy: dependencyIndex[key] || [], aliases: aliasIndex[key] || [] })); }, refreshIndex: (repoDir) => { indexPromise = refreshIndex(repoDir); manifestPromise = getManifests(repoDir); - dependentsPromise = manifestPromise.then(indexDependencies); + dependentsPromise = manifestPromise.then(createDependencyIndexes); return indexPromise; }, diff --git a/services/authoring/test/keys-repository-spec.js b/services/authoring/test/keys-repository-spec.js index 5c6d90dc0..d0737bdb9 100644 --- a/services/authoring/test/keys-repository-spec.js +++ b/services/authoring/test/keys-repository-spec.js @@ -98,7 +98,7 @@ describe('keys-repository', () => { it('should pull, delete files then commit and push', async () => { // Act - await target.deleteKey(testKeyPath, testAuthor); + await target.deleteKeys([testKeyPath], testAuthor); // Assert expect(mockGitRepo.deleteFile.callCount).to.equal(2); @@ -107,7 +107,7 @@ describe('keys-repository', () => { it('should delete the jpad rule file and the manifest file', async () => { // Act - await target.deleteKey(testKeyPath, testAuthor); + await target.deleteKeys([testKeyPath], testAuthor); // Assert const args = mockGitRepo.deleteFile.calls.map(x => x.arg); @@ -117,7 +117,7 @@ describe('keys-repository', () => { it('should commit and push with the author sent', async () => { // Act - await target.deleteKey(testKeyPath, testAuthor); + await target.deleteKeys([testKeyPath], testAuthor); // Assert expect(mockGitRepo.commitAndPush.calls[0].args[1]).to.equal(testAuthor); diff --git a/services/editor/package.json b/services/editor/package.json index 8c52ac65f..99faed9b8 100644 --- a/services/editor/package.json +++ b/services/editor/package.json @@ -1,6 +1,6 @@ { "name": "tweek-editor", - "version": "0.2.13", + "version": "0.3.0", "main": "dist/index.js", "repository": "Soluto/tweek", "author": "Soluto", diff --git a/services/editor/server/utils/request-error-handling-wrapper.js b/services/editor/server/utils/request-error-handling-wrapper.js index c3ea66d66..efae6571d 100644 --- a/services/editor/server/utils/request-error-handling-wrapper.js +++ b/services/editor/server/utils/request-error-handling-wrapper.js @@ -3,7 +3,7 @@ export default function requestErrorHandlingWrapper(handler) { try { await Promise.resolve(handler(req, res)); } catch (err) { - console.error(req.method, req.originalUrl, err); + console.error(req.method, req.originalUrl, err.message || err); res.status(500).send(err.message || 'Internal Server Error'); } }; diff --git a/services/editor/spec/unit/store/ducks/selectedKey-spec.js b/services/editor/spec/unit/store/ducks/selectedKey-spec.js index 10ffb7b58..2c5506c43 100644 --- a/services/editor/spec/unit/store/ducks/selectedKey-spec.js +++ b/services/editor/spec/unit/store/ducks/selectedKey-spec.js @@ -2,7 +2,6 @@ jest.unmock('../../../../src/store/ducks/tags'); jest.unmock('../../../../src/store/ducks/selectedKey'); jest.unmock('../../../../src/utils/http'); -jest.unmock('../../../../src/store/ducks/ducks-utils/validations/key-name-validations'); jest.unmock('../../../../src/store/ducks/ducks-utils/validations/key-value-type-validations'); jest.unmock('../../../../src/services/types-service'); jest.unmock('../../../../src/services/context-service'); @@ -22,7 +21,7 @@ import { openKey, saveKey, changeKeyValueType, - updateKeyName, + updateKeyPath, } from '../../../../src/store/ducks/selectedKey'; import { createBlankJPadKey, @@ -30,7 +29,6 @@ import { } from '../../../../src/store/ducks/ducks-utils/blankKeyDefinition'; import { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; -import keyNameValidations from '../../../../src/store/ducks/ducks-utils/validations/key-name-validations'; import keyValueTypeValidations from '../../../../src/store/ducks/ducks-utils/validations/key-value-type-validations'; import * as R from 'ramda'; @@ -44,6 +42,7 @@ describe('selectedKey', async () => { const SHOW_KEY_VALIDATIONS = 'SHOW_KEY_VALIDATIONS'; const KEY_VALUE_TYPE_CHANGE = 'KEY_VALUE_TYPE_CHANGE'; const KEY_VALIDATION_CHANGE = 'KEY_VALIDATION_CHANGE'; + const KEY_PATH_CHANGE = 'KEY_PATH_CHANGE'; const KEY_NAME_CHANGE = 'KEY_NAME_CHANGE'; const ADD_NOTIFICATION = 'ADD_NOTIFICATION'; @@ -415,7 +414,7 @@ describe('selectedKey', async () => { }); }); - describe('updateKeyName', () => { + describe('updateKeyPath', () => { it('should dispatch actions correctly', async () => { // Arrange const newKeyName = 'pita'; @@ -423,30 +422,34 @@ describe('selectedKey', async () => { const initializeState = generateState('some key', 'some new key'); initializeState.keys = []; - const expectedKeyNameValidation = keyNameValidations(newKeyName, []); - expectedKeyNameValidation.isShowingHint = false; - + const expectedKeyValidation = { isValid: true }; const expectedValidationPayload = { ...initializeState.selectedKey.validation, - key: expectedKeyNameValidation, + key: expectedKeyValidation, }; // Act - const func = updateKeyName(newKeyName); + const func = updateKeyPath(newKeyName, expectedKeyValidation); await func(dispatchMock, () => initializeState); // Assert - const keyNameChangeDispatchAction = dispatchMock.mock.calls[0][0]; - assertDispatchAction(keyNameChangeDispatchAction, { - type: KEY_NAME_CHANGE, - payload: newKeyName, - }); - - const keyValidationChangeDispatchAction = dispatchMock.mock.calls[1][0]; + const keyValidationChangeDispatchAction = dispatchMock.mock.calls[0][0]; assertDispatchAction(keyValidationChangeDispatchAction, { type: KEY_VALIDATION_CHANGE, payload: expectedValidationPayload, }); + + const keyPathChangeDispatchAction = dispatchMock.mock.calls[1][0]; + assertDispatchAction(keyPathChangeDispatchAction, { + type: KEY_PATH_CHANGE, + payload: newKeyName, + }); + + const keyNameChangeDispatchAction = dispatchMock.mock.calls[2][0]; + assertDispatchAction(keyNameChangeDispatchAction, { + type: KEY_NAME_CHANGE, + payload: newKeyName, + }); }); }); }); diff --git a/services/editor/spec/unit/store/ducks/ducks-utils/key-name-validations-spec.js b/services/editor/spec/unit/utils/key-name-validations-spec.js similarity index 84% rename from services/editor/spec/unit/store/ducks/ducks-utils/key-name-validations-spec.js rename to services/editor/spec/unit/utils/key-name-validations-spec.js index fa67666bc..96ef23b8d 100644 --- a/services/editor/spec/unit/store/ducks/ducks-utils/key-name-validations-spec.js +++ b/services/editor/spec/unit/utils/key-name-validations-spec.js @@ -1,10 +1,10 @@ /* global jest, beforeEach, describe, it, expect */ -jest.unmock('../../../../../src/store/ducks/ducks-utils/validations/key-name-validations'); +jest.unmock('../../../src/pages/keys/components/KeyPage/KeyAddPage/key-name-validations'); jest.unmock('chance'); import { assert, expect } from 'chai'; -import keyNameValidations from '../../../../../src/store/ducks/ducks-utils/validations/key-name-validations'; -import { BLANK_KEY_NAME } from '../../../../../src/store/ducks/ducks-utils/blankKeyDefinition'; +import keyNameValidations from '../../../src/pages/keys/components/KeyPage/KeyAddPage/key-name-validations'; +import { BLANK_KEY_NAME } from '../../../src/store/ducks/ducks-utils/blankKeyDefinition'; describe('key-name-validations', () => { const categoryName1 = 'someCategoryName1'; @@ -65,9 +65,9 @@ describe('key-name-validations', () => { // Assert expect(validationResult.isValid).to.equal( x.expectedIsValid, - `should return value is ${x.expectedIsValid - ? '' - : 'in'}valid (hint: ${validationResult.hint})`, + `should return value is ${x.expectedIsValid ? '' : 'in'}valid (hint: ${ + validationResult.hint + })`, ); if (!validationResult.isValid) assert(validationResult.hint.length > 0, 'should return an un empty hint'); diff --git a/services/editor/src/components/alerts/Alerts.js b/services/editor/src/components/alerts/Alerts.js index 17ec4d1cb..55a5984f2 100644 --- a/services/editor/src/components/alerts/Alerts.js +++ b/services/editor/src/components/alerts/Alerts.js @@ -1,40 +1,55 @@ import React from 'react'; import { connect } from 'react-redux'; +import { withState, setDisplayName, compose } from 'recompose'; import Rodal from 'rodal'; import './Alerts.css'; -const reactify = (Content, props) => - typeof Content === 'string' - ?
- {Content.split('\n').map((line, i) => -
- {line} -
, - )} -
- : ; +const addState = compose(setDisplayName('Alert'), withState('componentData', 'setComponentData')); -const Alert = ({ title, message, buttons, onClose, showCloseButton = false }) => - - {title ? reactify(title, { className: 'rodal-header' }) : null} - {reactify(message, { className: 'rodal-body' })} -
- {buttons.map(({ text, ...props }, i) => - , - )} -
-
; +const reactify = (Content, props) => + typeof Content === 'string' ? ( +
{Content.split('\n').map((line, i) =>
{line}
)}
+ ) : ( + + ); -export default connect(state => state)(({ alerts }) => -
- {alerts.map(({ id: key, ...alert }) => )} -
, +const Alert = addState( + ({ + title, + message, + component: Component, + buttons, + onClose, + showCloseButton = false, + componentData, + setComponentData, + }) => ( + + {title && reactify(title, { className: 'rodal-header' })} + {message && reactify(message, { className: 'rodal-body' })} + {Component && } +
+ {buttons.map(({ text, validate, onClick, ...props }, i) => ( + + ))} +
+
+ ), ); + +export default connect(state => state)(({ alerts }) => ( +
{alerts.map(({ id: key, ...alert }) => )}
+)); diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.css b/services/editor/src/components/common/EditableText/EditableText.css similarity index 100% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.css rename to services/editor/src/components/common/EditableText/EditableText.css diff --git a/services/editor/src/components/common/EditableText/EditableText.js b/services/editor/src/components/common/EditableText/EditableText.js new file mode 100644 index 000000000..6be5233cb --- /dev/null +++ b/services/editor/src/components/common/EditableText/EditableText.js @@ -0,0 +1,58 @@ +import React from 'react'; +import classNames from 'classnames'; +import { withState } from 'recompose'; +import wrapComponentWithClass from '../../../hoc/wrap-component-with-class'; +import './EditableText.css'; + +const EditableText = withState('isInEditMode', 'setIsInEditMode', false)( + ({ + value, + placeHolder, + maxLength, + classNames: classes = {}, + isInEditMode, + setIsInEditMode, + onTextChanged = () => {}, + isReadonly, + ...props + }) => ( +
+ {isInEditMode ? ( +
{ + setIsInEditMode(false); + e.preventDefault(); + }} + className={classNames('editable-text-form', classes.form)} + > + input && input.focus()} + className={classNames('editable-text-input', classes.input)} + onChange={e => onTextChanged(e.target.value)} + value={value} + placeholder={placeHolder} + onBlur={() => setIsInEditMode(false)} + maxLength={maxLength} + /> +
+ ) : ( +
isReadonly || setIsInEditMode(true)} + > + {value} +
+ )} +
+ ), +); + +export default wrapComponentWithClass(EditableText); diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.less b/services/editor/src/components/common/EditableText/EditableText.less similarity index 78% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.less rename to services/editor/src/components/common/EditableText/EditableText.less index 23a7409ac..d2ebe1ee6 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.less +++ b/services/editor/src/components/common/EditableText/EditableText.less @@ -1,4 +1,4 @@ -@import (reference) "../../../../../../styles/core/core.less"; +@import (reference) "../../../styles/core/core.less"; .editable-text-container { @text-color: #515c66; border: 1px solid transparent; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.css b/services/editor/src/components/common/EditableTextArea/EditableTextArea.css similarity index 100% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.css rename to services/editor/src/components/common/EditableTextArea/EditableTextArea.css diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.js b/services/editor/src/components/common/EditableTextArea/EditableTextArea.js similarity index 89% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.js rename to services/editor/src/components/common/EditableTextArea/EditableTextArea.js index 84e9c4b77..f10c0978b 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.js +++ b/services/editor/src/components/common/EditableTextArea/EditableTextArea.js @@ -4,9 +4,7 @@ import { compose, withState } from 'recompose'; import TextareaAutosize from 'react-autosize-textarea'; import './EditableTextArea.css'; -const EditableTextArea = compose( - withState('isInEditMode', 'setIsInEditMode', false), -)( +const EditableTextArea = compose(withState('isInEditMode', 'setIsInEditMode', false))( ({ value, placeHolder, @@ -16,7 +14,7 @@ const EditableTextArea = compose( isInEditMode, setIsInEditMode, onTextChanged = () => {}, - }) => + }) => (
-
, + + ), ); export default EditableTextArea; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.less b/services/editor/src/components/common/EditableTextArea/EditableTextArea.less similarity index 83% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.less rename to services/editor/src/components/common/EditableTextArea/EditableTextArea.less index ac5dc481c..d9b03387c 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableTextArea/EditableTextArea.less +++ b/services/editor/src/components/common/EditableTextArea/EditableTextArea.less @@ -1,4 +1,4 @@ -@import (reference) "../../../../../../styles/core/core.less"; +@import (reference) "../../../styles/core/core.less"; .textarea-container { .textarea-input { display: block; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.css b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.css index 456c084fd..602e7ab87 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.css +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.css @@ -42,339 +42,6 @@ align-items: center; padding-bottom: 1px; } -.add-key-page .add-key-input-wrapper .keypath-input { - width: 100%; - display: flex; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-input { - flex-grow: 1; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input { - display: inline-block; - border: 0 none; - border-bottom: 1px solid rgba(0, 122, 204, 0.5); - height: 28px; - width: 150px; - padding: 0 4px; - background-color: transparent; - font-size: 15px; - font-weight: 500; - color: #515C66; - outline: none; - box-sizing: border-box; - transition: all 0.2s ease-in-out; - width: 100%; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { - border-bottom: 2px solid rgba(0, 122, 204, 0.8); -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { - border-color: #bcbcbc; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu { - position: absolute; - max-height: 350px; - min-width: 100%; - overflow-y: auto; - width: auto; - z-index: 5; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu li { - background-color: #f4f4f4; - min-height: 35px; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.2); - border-bottom-width: 0; - overflow-x: hidden; - transition: all 0.2s ease-in-out; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu li:last-child { - border-bottom-width: 1px; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu li:hover { - cursor: pointer; - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu li:active { - background-color: #d1d1d1; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu li a { - text-decoration: none; - color: gray; - font-size: 13px; - width: 100%; - height: 100%; - display: flex; - flex-grow: 1; - flex-direction: column; - justify-content: center; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu li a:first-child { - padding: 10px; - padding-right: 30px; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu .disabled { - display: none; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .override-dropdown .dropdown-menu .active { - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead { - flex-grow: 1; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input { - display: inline-block; - border: 0 none; - border-bottom: 1px solid rgba(0, 122, 204, 0.5); - height: 28px; - width: 150px; - padding: 0 4px; - background-color: transparent; - font-size: 15px; - font-weight: 500; - color: #515C66; - outline: none; - box-sizing: border-box; - transition: all 0.2s ease-in-out; - width: 100%; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { - border-bottom: 2px solid rgba(0, 122, 204, 0.8); -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { - border-color: #bcbcbc; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu { - position: absolute; - max-height: 350px; - min-width: 100%; - overflow-y: auto; - width: auto; - z-index: 5; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu li { - background-color: #f4f4f4; - min-height: 35px; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.2); - border-bottom-width: 0; - overflow-x: hidden; - transition: all 0.2s ease-in-out; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu li:last-child { - border-bottom-width: 1px; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu li:hover { - cursor: pointer; - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu li:active { - background-color: #d1d1d1; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu li a { - text-decoration: none; - color: gray; - font-size: 13px; - width: 100%; - height: 100%; - display: flex; - flex-grow: 1; - flex-direction: column; - justify-content: center; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu li a:first-child { - padding: 10px; - padding-right: 30px; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu .disabled { - display: none; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-typeahead .bootstrap-typeahead .dropdown-menu .active { - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-input { - flex-grow: 1; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input { - display: inline-block; - border: 0 none; - border-bottom: 1px solid rgba(0, 122, 204, 0.5); - height: 28px; - width: 150px; - padding: 0 4px; - background-color: transparent; - font-size: 15px; - font-weight: 500; - color: #515C66; - outline: none; - box-sizing: border-box; - transition: all 0.2s ease-in-out; - width: 100%; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { - border-bottom: 2px solid rgba(0, 122, 204, 0.8); -} -.add-key-page .add-key-input-wrapper .keypath-input .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { - border-color: #bcbcbc; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu { - position: absolute; - max-height: 350px; - min-width: 100%; - overflow-y: auto; - width: auto; - z-index: 5; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu li { - background-color: #f4f4f4; - min-height: 35px; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.2); - border-bottom-width: 0; - overflow-x: hidden; - transition: all 0.2s ease-in-out; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu li:last-child { - border-bottom-width: 1px; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu li:hover { - cursor: pointer; - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu li:active { - background-color: #d1d1d1; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu li a { - text-decoration: none; - color: gray; - font-size: 13px; - width: 100%; - height: 100%; - display: flex; - flex-grow: 1; - flex-direction: column; - justify-content: center; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu li a:first-child { - padding: 10px; - padding-right: 30px; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu .disabled { - display: none; -} -.add-key-page .add-key-input-wrapper .keypath-input .override-dropdown .dropdown-menu .active { - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead { - flex-grow: 1; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input { - display: inline-block; - border: 0 none; - border-bottom: 1px solid rgba(0, 122, 204, 0.5); - height: 28px; - width: 150px; - padding: 0 4px; - background-color: transparent; - font-size: 15px; - font-weight: 500; - color: #515C66; - outline: none; - box-sizing: border-box; - transition: all 0.2s ease-in-out; - width: 100%; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { - border-bottom: 2px solid rgba(0, 122, 204, 0.8); -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { - border-color: #bcbcbc; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu { - position: absolute; - max-height: 350px; - min-width: 100%; - overflow-y: auto; - width: auto; - z-index: 5; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu li { - background-color: #f4f4f4; - min-height: 35px; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.2); - border-bottom-width: 0; - overflow-x: hidden; - transition: all 0.2s ease-in-out; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu li:last-child { - border-bottom-width: 1px; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu li:hover { - cursor: pointer; - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu li:active { - background-color: #d1d1d1; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu li a { - text-decoration: none; - color: gray; - font-size: 13px; - width: 100%; - height: 100%; - display: flex; - flex-grow: 1; - flex-direction: column; - justify-content: center; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu li a:first-child { - padding: 10px; - padding-right: 30px; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu .disabled { - display: none; -} -.add-key-page .add-key-input-wrapper .keypath-input .bootstrap-typeahead .dropdown-menu .active { - background-color: #dfdfdf; -} -.add-key-page .add-key-input-wrapper .keypath-input .auto-suggest-wrapper { - width: 100%; - display: flex; -} -.add-key-page .add-key-input-wrapper .keypath-input .auto-suggest-wrapper .bootstrap-typeahead-input { - padding-left: 10px; - font-size: 15px; - height: auto; -} -.add-key-page .add-key-input-wrapper .keypath-input .auto-suggest-wrapper[data-with-error="true"] .bootstrap-typeahead-input { - padding-left: 30px; - font-size: 15px; - height: auto; -} -.add-key-page .add-key-input-wrapper .keypath-input .auto-suggest-wrapper .validation-icon-wrapper { - flex-direction: row; - width: 0; - margin: 11px 0 0 0; - position: absolute; - z-index: 7; - transition: all 0.2s ease-in-out; -} -.add-key-page .add-key-input-wrapper .keypath-input .auto-suggest-wrapper .validation-icon-wrapper[data-is-shown="true"] { - width: 16px; - height: 16px; - margin-top: 0px; - padding: 0px 5px 3px 5px; -} -.add-key-page .add-key-input-wrapper .keypath-input .combo-box-default-wrapper-theme-class { - display: flex; - flex-grow: 1; - align-content: space-between; -} .add-key-page .add-key-properties-wrapper { display: flex; flex-direction: row; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.js b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.js index cc4c63a0d..1d074f134 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.js @@ -2,15 +2,27 @@ import React from 'react'; import { compose, setDisplayName, setPropTypes } from 'recompose'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import KeyValueTypeSelector from '../KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector'; -import NewKeyInput from '../KeyEditPage/NewKeyInput'; -import { addKeyDetails, updateKeyPath, changeKeyFormat } from '../../../../../store/ducks/selectedKey'; +import { + addKeyDetails, + updateKeyPath, + changeKeyFormat, +} from '../../../../../store/ducks/selectedKey'; +import KeyValueTypeSelector from './KeyValueTypeSelector/KeyValueTypeSelector'; +import NewKeyInput from './NewKeyInput'; import KeyFormatSelector from './KeyFormatSelector'; import './KeyAddPage.css'; const KeyAddPage = compose( - connect((state => ({ manifest: state.selectedKey.local.manifest })), - { addKeyDetails, updateKeyPath, changeKeyFormat } + connect( + ({ selectedKey: { local: { manifest }, validation: { key: keyValidation } } }) => ({ + manifest, + keyValidation, + }), + { + addKeyDetails, + updateKeyPath, + changeKeyFormat, + }, ), setDisplayName('KeyAddPage'), setPropTypes({ @@ -19,7 +31,7 @@ const KeyAddPage = compose( changeKeyFormat: PropTypes.func.isRequired, manifest: PropTypes.object.isRequired, }), -)(({ manifest, updateKeyPath, addKeyDetails, changeKeyFormat }) => { +)(({ manifest, updateKeyPath, addKeyDetails, changeKeyFormat, keyValidation }) => { const valueType = manifest.valueType; const displayName = manifest.meta.name; return ( @@ -27,9 +39,11 @@ const KeyAddPage = compose(

Add new Key

-
- updateKeyPath(name)} displayName={displayName} /> -
+
diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.less b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.less index c3cbc2d62..19c7d0f8a 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.less +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyAddPage.less @@ -81,17 +81,6 @@ align-items: center; padding-bottom: 1px; } - - .keypath-input { - width: 100%; - .combo-box-basic(@dropdown-min-width: 100%, @input-width: 100%, @font-size: @smaller-font); - .auto-suggest-wrapper { - width: 100%; - display: flex; - @with-validation-icon(); - } - @with-adjusted-combo-box-wrapper(); - } } .add-key-properties-wrapper { display: flex; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.css b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.css similarity index 100% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.css rename to services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.css diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.js b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.js similarity index 84% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.js rename to services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.js index 197348814..0c6cd08ae 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.js @@ -1,5 +1,4 @@ import React from 'react'; -import { compose } from 'recompose'; import { connect } from 'react-redux'; import changeCase from 'change-case'; import ComboBox from '../../../../../../components/common/ComboBox/ComboBox'; @@ -14,14 +13,12 @@ const getValueTypeSuggestions = () => value: x, })); -const KeyValueTypeSelector = compose( - connect( - state => ({ - selectedKey: state.selectedKey, - validation: state.selectedKey.validation.manifest.valueType, - }), - { changeKeyValueType }, - ), +const KeyValueTypeSelector = connect( + state => ({ + selectedKey: state.selectedKey, + validation: state.selectedKey.validation.manifest.valueType, + }), + { changeKeyValueType }, )(({ value, validation: { isShowingHint, hint }, changeKeyValueType: onChange }) => { const suggestions = getValueTypeSuggestions(); return ( diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.less b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.less similarity index 100% rename from services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyValueTypeSelector/KeyValueTypeSelector.less rename to services/editor/src/pages/keys/components/KeyPage/KeyAddPage/KeyValueTypeSelector/KeyValueTypeSelector.less diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.css b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.css new file mode 100644 index 000000000..f67e11337 --- /dev/null +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.css @@ -0,0 +1,333 @@ +.keypath-input-wrapper { + width: 100%; + display: flex; +} +.keypath-input-wrapper .override-typeahead .override-input { + flex-grow: 1; +} +.keypath-input-wrapper .override-typeahead .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input { + display: inline-block; + border: 0 none; + border-bottom: 1px solid rgba(0, 122, 204, 0.5); + height: 28px; + width: 150px; + padding: 0 4px; + background-color: transparent; + font-size: 15px; + font-weight: 500; + color: #515C66; + outline: none; + box-sizing: border-box; + transition: all 0.2s ease-in-out; + width: 100%; +} +.keypath-input-wrapper .override-typeahead .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { + border-bottom: 2px solid rgba(0, 122, 204, 0.8); +} +.keypath-input-wrapper .override-typeahead .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { + border-color: #bcbcbc; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu { + position: absolute; + max-height: 350px; + min-width: 100%; + overflow-y: auto; + width: auto; + z-index: 5; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu li { + background-color: #f4f4f4; + min-height: 35px; + display: flex; + align-items: center; + border: 1px solid rgba(0, 0, 0, 0.2); + border-bottom-width: 0; + overflow-x: hidden; + transition: all 0.2s ease-in-out; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu li:last-child { + border-bottom-width: 1px; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu li:hover { + cursor: pointer; + background-color: #dfdfdf; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu li:active { + background-color: #d1d1d1; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu li a { + text-decoration: none; + color: gray; + font-size: 13px; + width: 100%; + height: 100%; + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: center; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu li a:first-child { + padding: 10px; + padding-right: 30px; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu .disabled { + display: none; +} +.keypath-input-wrapper .override-typeahead .override-dropdown .dropdown-menu .active { + background-color: #dfdfdf; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead { + flex-grow: 1; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input { + display: inline-block; + border: 0 none; + border-bottom: 1px solid rgba(0, 122, 204, 0.5); + height: 28px; + width: 150px; + padding: 0 4px; + background-color: transparent; + font-size: 15px; + font-weight: 500; + color: #515C66; + outline: none; + box-sizing: border-box; + transition: all 0.2s ease-in-out; + width: 100%; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { + border-bottom: 2px solid rgba(0, 122, 204, 0.8); +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { + border-color: #bcbcbc; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu { + position: absolute; + max-height: 350px; + min-width: 100%; + overflow-y: auto; + width: auto; + z-index: 5; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu li { + background-color: #f4f4f4; + min-height: 35px; + display: flex; + align-items: center; + border: 1px solid rgba(0, 0, 0, 0.2); + border-bottom-width: 0; + overflow-x: hidden; + transition: all 0.2s ease-in-out; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu li:last-child { + border-bottom-width: 1px; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu li:hover { + cursor: pointer; + background-color: #dfdfdf; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu li:active { + background-color: #d1d1d1; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu li a { + text-decoration: none; + color: gray; + font-size: 13px; + width: 100%; + height: 100%; + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: center; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu li a:first-child { + padding: 10px; + padding-right: 30px; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu .disabled { + display: none; +} +.keypath-input-wrapper .override-typeahead .bootstrap-typeahead .dropdown-menu .active { + background-color: #dfdfdf; +} +.keypath-input-wrapper .override-input { + flex-grow: 1; +} +.keypath-input-wrapper .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input { + display: inline-block; + border: 0 none; + border-bottom: 1px solid rgba(0, 122, 204, 0.5); + height: 28px; + width: 150px; + padding: 0 4px; + background-color: transparent; + font-size: 15px; + font-weight: 500; + color: #515C66; + outline: none; + box-sizing: border-box; + transition: all 0.2s ease-in-out; + width: 100%; +} +.keypath-input-wrapper .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { + border-bottom: 2px solid rgba(0, 122, 204, 0.8); +} +.keypath-input-wrapper .override-input .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { + border-color: #bcbcbc; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu { + position: absolute; + max-height: 350px; + min-width: 100%; + overflow-y: auto; + width: auto; + z-index: 5; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu li { + background-color: #f4f4f4; + min-height: 35px; + display: flex; + align-items: center; + border: 1px solid rgba(0, 0, 0, 0.2); + border-bottom-width: 0; + overflow-x: hidden; + transition: all 0.2s ease-in-out; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu li:last-child { + border-bottom-width: 1px; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu li:hover { + cursor: pointer; + background-color: #dfdfdf; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu li:active { + background-color: #d1d1d1; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu li a { + text-decoration: none; + color: gray; + font-size: 13px; + width: 100%; + height: 100%; + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: center; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu li a:first-child { + padding: 10px; + padding-right: 30px; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu .disabled { + display: none; +} +.keypath-input-wrapper .override-dropdown .dropdown-menu .active { + background-color: #dfdfdf; +} +.keypath-input-wrapper .bootstrap-typeahead { + flex-grow: 1; +} +.keypath-input-wrapper .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input { + display: inline-block; + border: 0 none; + border-bottom: 1px solid rgba(0, 122, 204, 0.5); + height: 28px; + width: 150px; + padding: 0 4px; + background-color: transparent; + font-size: 15px; + font-weight: 500; + color: #515C66; + outline: none; + box-sizing: border-box; + transition: all 0.2s ease-in-out; + width: 100%; +} +.keypath-input-wrapper .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { + border-bottom: 2px solid rgba(0, 122, 204, 0.8); +} +.keypath-input-wrapper .bootstrap-typeahead .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { + border-color: #bcbcbc; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu { + position: absolute; + max-height: 350px; + min-width: 100%; + overflow-y: auto; + width: auto; + z-index: 5; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu li { + background-color: #f4f4f4; + min-height: 35px; + display: flex; + align-items: center; + border: 1px solid rgba(0, 0, 0, 0.2); + border-bottom-width: 0; + overflow-x: hidden; + transition: all 0.2s ease-in-out; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu li:last-child { + border-bottom-width: 1px; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu li:hover { + cursor: pointer; + background-color: #dfdfdf; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu li:active { + background-color: #d1d1d1; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu li a { + text-decoration: none; + color: gray; + font-size: 13px; + width: 100%; + height: 100%; + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: center; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu li a:first-child { + padding: 10px; + padding-right: 30px; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu .disabled { + display: none; +} +.keypath-input-wrapper .bootstrap-typeahead .dropdown-menu .active { + background-color: #dfdfdf; +} +.keypath-input-wrapper .keypath-input-container { + width: 100%; + display: flex; +} +.keypath-input-wrapper .keypath-input-container .bootstrap-typeahead-input { + padding-left: 10px; + font-size: 15px; + height: auto; +} +.keypath-input-wrapper .keypath-input-container[data-with-error="true"] .bootstrap-typeahead-input { + padding-left: 30px; + font-size: 15px; + height: auto; +} +.keypath-input-wrapper .keypath-input-container .validation-icon-wrapper { + flex-direction: row; + width: 0; + margin: 11px 0 0 0; + position: absolute; + z-index: 7; + transition: all 0.2s ease-in-out; +} +.keypath-input-wrapper .keypath-input-container .validation-icon-wrapper[data-is-shown="true"] { + width: 16px; + height: 16px; + margin-top: 0px; + padding: 0px 5px 3px 5px; +} +.keypath-input-wrapper .combo-box-default-wrapper-theme-class { + display: flex; + flex-grow: 1; + align-content: space-between; +} diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.js b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.js new file mode 100644 index 000000000..8d83a177a --- /dev/null +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.js @@ -0,0 +1,69 @@ +import React from 'react'; +import * as R from 'ramda'; +import { connect } from 'react-redux'; +import { Observable } from 'rxjs'; +import { compose, mapPropsStream, lifecycle } from 'recompose'; +import * as SearchService from '../../../../../services/search-service'; +import ComboBox from '../../../../../components/common/ComboBox/ComboBox'; +import ValidationIcon from '../../../../../components/common/ValidationIcon'; +import keyNameValidations from './key-name-validations'; +import './NewKeyInput.css'; + +const getKeyPrefix = path => R.slice(0, -1, path.split('/')).join('/'); +const getSugesstions = R.pipe(R.map(getKeyPrefix), R.uniq(), R.filter(x => x !== '')); + +function getKeyNameSuggestions(keysList) { + return getSugesstions(keysList).sort(); +} + +const NewKeyInput = compose( + connect(state => ({ keysList: state.keys })), + mapPropsStream((prop$) => { + const keysList$ = prop$ + .pluck('keysList') + .distinctUntilChanged() + .switchMap(SearchService.filterInternalKeys); + + return Observable.combineLatest(prop$, keysList$, (props, keysList) => ({ + ...props, + keysList, + })); + }), + lifecycle({ + componentWillMount() { + const { displayName, keysList, onChange } = this.props; + let validation = keyNameValidations(displayName, keysList); + validation.isShowingHint = false; + onChange(displayName, validation); + }, + }), +)(({ keysList, validation: { isShowingHint = false, hint } = {}, onChange, displayName }) => { + const suggestions = getKeyNameSuggestions(keysList).map(x => ({ label: x, value: x })); + return ( +
+
+ + { + const validation = keyNameValidations(text, keysList); + validation.isShowingHint = !validation.isValid; + onChange(text, validation); + }} + showValueInOptions + /> +
+
+ ); +}); + +NewKeyInput.displayName = 'NewKeyInput'; + +export default NewKeyInput; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.less b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.less new file mode 100644 index 000000000..4b202a5fb --- /dev/null +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/NewKeyInput.less @@ -0,0 +1,12 @@ +@import (reference) "./KeyAddPage.less"; + +.keypath-input-wrapper { + width: 100%; + .combo-box-basic(@dropdown-min-width: 100%, @input-width: 100%, @font-size: @smaller-font); + .keypath-input-container { + width: 100%; + display: flex; + @with-validation-icon(); + } + @with-adjusted-combo-box-wrapper(); +} diff --git a/services/editor/src/store/ducks/ducks-utils/validations/key-name-validations.js b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/key-name-validations.js similarity index 87% rename from services/editor/src/store/ducks/ducks-utils/validations/key-name-validations.js rename to services/editor/src/pages/keys/components/KeyPage/KeyAddPage/key-name-validations.js index 949020e73..a0a243e96 100644 --- a/services/editor/src/store/ducks/ducks-utils/validations/key-name-validations.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyAddPage/key-name-validations.js @@ -1,4 +1,4 @@ -import { BLANK_KEY_NAME } from '../blankKeyDefinition'; +import { BLANK_KEY_NAME } from '../../../../../store/ducks/ducks-utils/blankKeyDefinition'; const lengthValidation = { rule: ({ value }) => value.length > 0, @@ -41,5 +41,5 @@ let keyNameValidations = [ export default function (keyName, keysList) { let failedRule = keyNameValidations.find(x => !x.rule({ value: keyName, keysList })); - return { isValid: !failedRule, hint: failedRule ? failedRule.hint : undefined }; + return { isValid: !failedRule, hint: failedRule && failedRule.hint }; } diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.css b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.css index 158b118dd..09e7ec2e0 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.css +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.css @@ -1,4 +1,4 @@ -.key-dependency-indicator-container { +.dependency-indicator-container { display: flex; flex-direction: column; flex-grow: 1; @@ -7,59 +7,38 @@ margin-top: 10px; padding-left: 4px; } -.dependency-item { +.dependency-indicator-container .dependency-item { list-style-type: none; font-weight: 300; -} -.depends-on { - display: flex; - flex-direction: column; - flex-grow: 1; color: #a5a5a5; - font-size: 14px; - margin-top: 10px; - padding-left: 4px; } -.depends-on li { - list-style-type: none; - font-weight: 300; -} -.depends-on li a { +.dependency-indicator-container .dependency-item a { text-decoration: none; color: #a5a5a5; } -.depends-on li a:visited { +.dependency-indicator-container .dependency-item a:visited { color: #a5a5a5; } -.depends-on li a:hover { +.dependency-indicator-container .dependency-item a:hover { color: #727272; } -.depends-on li a:active { - color: #a5a5a5; -} -.used-by { - display: flex; - flex-direction: column; - flex-grow: 1; +.dependency-indicator-container .dependency-item a:active { color: #a5a5a5; - font-size: 14px; - margin-top: 10px; - padding-left: 4px; } -.used-by li { - list-style-type: none; - font-weight: 300; +.dependency-indicator-container .dependency-item [data-comp="delete-alias"] { + width: 22px; + height: 22px; + border-radius: 50%; + border: none; + cursor: pointer; + background: none; } -.used-by li a { - text-decoration: none; - color: #a5a5a5; -} -.used-by li a:visited { - color: #a5a5a5; +.dependency-indicator-container .dependency-item [data-comp="delete-alias"]:disabled { + cursor: default; } -.used-by li a:hover { - color: #727272; +.dependency-indicator-container .dependency-item [data-comp="delete-alias"]:hover:not(:disabled) { + background: rgba(215, 215, 215, 0.49); } -.used-by li a:active { - color: #a5a5a5; +.dependency-indicator-container .dependency-item [data-comp="delete-alias"] img { + width: 22px; } diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.js b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.js index ddfa2b6d5..4546cf1b2 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.js @@ -1,48 +1,61 @@ import React from 'react'; import { Link } from 'react-router-dom'; import AnimakitExpander from 'animakit-expander'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import { withState, setPropTypes, compose } from 'recompose'; +import { withState } from 'recompose'; +import trashIcon from '../../../../../../resources/trash-icon.svg'; import './DependencyIndicator.css'; -const ExpanderToggle = ({ toggled, onToggle, dataComp }) => +const ExpanderToggle = ({ toggled, onToggle }) => ( onToggle(current => !current)} style={{ cursor: 'pointer', fontFamily: 'monospaced', color: '#a5a5a5' }} > {toggled ? '[-]' : '[+]'} - ; - -const createDependenciesList = (componentName, caption) => - compose( - withState('toggled', 'onToggle', false), - setPropTypes({ items: PropTypes.array }), - )(({ items, toggled, onToggle }) => -
- {(items && items.length) - ?
- - {caption}
- -
    - {items.map(dep =>
  • {dep}
  • )} -
-
-
- :
} -
, - ); - -export const DependsOn = createDependenciesList('depends-on', 'Depends on:'); - -export const UsedBy = createDependenciesList('used-by', 'Used by:'); + +); + +const withToggleState = withState('toggled', 'onToggle', false); + +const Expander = withToggleState(({ title, toggled, onToggle, children, ...props }) => ( +
+ + {title} +
+ + {children} + +
+)); + +const renderLink = dep => {dep}; +const renderText = (dep, { deleteAlias }) => ( +
+ {dep} + +
+); + +const createDependenciesList = (componentName, title, renderElement) => ({ items, ...props }) => ( +
+ {items && items.length ? ( + +
    + {items.map(dep => ( +
  • + {renderElement(dep, props)} +
  • + ))} +
+
+ ) : null} +
+); + +export const DependsOn = createDependenciesList('depends-on', 'Depends on:', renderLink); + +export const UsedBy = createDependenciesList('used-by', 'Used by:', renderLink); + +export const Aliases = createDependenciesList('aliases', 'Aliases:', renderText); diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.less b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.less index bae95ddef..16d36fcfa 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.less +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/DependencyIndicator/DependencyIndicator.less @@ -1,7 +1,8 @@ @import (reference) "../../../../../../styles/core/core.less"; + @text-color: #a5a5a5; -.key-dependency-indicator-container { +.dependency-indicator-container { display: flex; flex-direction: column; flex-grow: 1; @@ -9,17 +10,12 @@ font-size: 14px; margin-top: 10px; padding-left: 4px; -} -.dependency-item { - list-style-type: none; - font-weight: 300; -} + .dependency-item { + list-style-type: none; + font-weight: 300; + color: @text-color; -.depends-on { - .key-dependency-indicator-container; - li { - .dependency-item; a { text-decoration: none; color: @text-color; @@ -33,25 +29,24 @@ color: @text-color; } } - } -} -.used-by { - .key-dependency-indicator-container; - li { - .dependency-item; - a { - text-decoration: none; - color: @text-color; - &:visited { - color: @text-color; + [data-comp= "delete-alias"] { + @icon-size: 22px; + width: @icon-size; + height: @icon-size; + border-radius: 50%; + border: none; + cursor: pointer; + background: none; + &:disabled { + cursor: default; } - &:hover { - color: darken(@text-color, 20%); + &:hover:not(:disabled) { + background: rgba(215, 215, 215, 0.49); } - &:active { - color: @text-color; + img { + width: @icon-size; } } } -} \ No newline at end of file +} diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.js b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.js deleted file mode 100644 index 565d99eeb..000000000 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/EditableText/EditableText.js +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { withState } from 'recompose'; -import wrapComponentWithClass from '../../../../../../hoc/wrap-component-with-class'; -import './EditableText.css'; - -const EditableText = withState( - 'isInEditMode', - 'setIsInEditMode', - false, -)( - ({ - value, - placeHolder, - maxLength, - classNames: classes = {}, - isInEditMode, - setIsInEditMode, - onTextChanged = () => {}, - isReadonly, - ...props - }) => -
- {isInEditMode - ?
{ - setIsInEditMode(false); - e.preventDefault(); - }} - className={classNames('editable-text-form', classes.form)} - > - input && input.focus()} - className={classNames('editable-text-input', classes.input)} - onChange={e => onTextChanged(e.target.value)} - value={value} - placeholder={placeHolder} - onBlur={() => setIsInEditMode(false)} - maxLength={maxLength} - /> -
- :
isReadonly || setIsInEditMode(true)} - > - {value} -
} -
, -); - -export default wrapComponentWithClass(EditableText); diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/HeaderMainInput.js b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/HeaderMainInput.js index 793fc5d40..8ce627bc6 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/HeaderMainInput.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/HeaderMainInput.js @@ -1,12 +1,12 @@ import React from 'react'; -import EditableText from './EditableText/EditableText'; +import EditableText from '../../../../../components/common/EditableText/EditableText'; const HeaderMainInput = ({ onKeyNameChanged, onDisplayNameChanged, keyManifest: { meta: { name: displayName, archived }, valueType }, isReadonly, -}) => +}) => (
-
; +
+); export default HeaderMainInput; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.css b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.css index f54fbfb82..2f78d8aa8 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.css +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.css @@ -97,91 +97,6 @@ .key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .validation-message { font-size: 13px; } -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper { - display: flex; - flex-grow: 1; - flex-direction: row; - margin-bottom: 13px; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .bootstrap-typeahead-input-container { - display: flex; - flex-grow: 1; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .bootstrap-typeahead-input-container .bootstrap-typeahead-input { - display: inline-block; - border: 0 none; - border-bottom: 1px solid rgba(0, 122, 204, 0.5); - height: 28px; - width: 150px; - padding: 0 4px; - background-color: transparent; - font-size: 13px; - font-weight: 500; - color: #515C66; - outline: none; - box-sizing: border-box; - transition: all 0.2s ease-in-out; - font-size: 22px; - font-weight: 300; - margin-right: 20px; - display: flex; - flex-grow: 1; - padding-left: 0; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { - border-bottom: 2px solid rgba(0, 122, 204, 0.8); -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { - border-color: #bcbcbc; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper[data-with-error="true"] .bootstrap-typeahead-input-container { - display: flex; - flex-grow: 1; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper[data-with-error="true"] .bootstrap-typeahead-input-container .bootstrap-typeahead-input { - display: inline-block; - border: 0 none; - border-bottom: 1px solid rgba(0, 122, 204, 0.5); - height: 28px; - width: 150px; - padding: 0 4px; - background-color: transparent; - font-size: 13px; - font-weight: 500; - color: #515C66; - outline: none; - box-sizing: border-box; - transition: all 0.2s ease-in-out; - font-size: 22px; - font-weight: 300; - margin-right: 20px; - display: flex; - flex-grow: 1; - padding-left: 30px; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper[data-with-error="true"] .bootstrap-typeahead-input-container .bootstrap-typeahead-input:focus { - border-bottom: 2px solid rgba(0, 122, 204, 0.8); -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper[data-with-error="true"] .bootstrap-typeahead-input-container .bootstrap-typeahead-input:disabled { - border-color: #bcbcbc; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .validation-icon-wrapper { - flex-direction: row; - width: 0; - margin: 11px 0 0 0; - position: absolute; - z-index: 7; - transition: all 0.2s ease-in-out; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .validation-icon-wrapper[data-is-shown="true"] { - width: 16px; - height: 16px; - margin-top: 5px; - padding: 3px 5px; -} -.key-edit-page .key-viewer-container-fieldset .key-viewer-container .key-main-input .auto-suggest-wrapper .auto-suggest { - flex-grow: 1; -} .key-edit-page .key-viewer-container-fieldset .sticky-key-header { position: absolute; height: 72px; diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.js b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.js index f6ac2fa80..5006fc54f 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.js @@ -5,11 +5,11 @@ import JPadFullEditor from '../../../../../components/JPadFullEditor/JPadFullEdi import stickyHeaderIdentifier from '../../../../../hoc/sticky-header-identifier'; import ConstEditor from '../../../../../components/ConstEditor'; import KeyTags from './KeyTags/KeyTags'; -import EditableTextArea from './EditableTextArea/EditableTextArea'; +import EditableTextArea from '../../../../../components/common/EditableTextArea/EditableTextArea'; import RevisionHistory from './RevisionHistory/RevisionHistory'; import KeyPageActions from './KeyPageActions/KeyPageActions'; import HeaderMainInput from './HeaderMainInput'; -import { UsedBy, DependsOn } from './DependencyIndicator/DependencyIndicator'; +import { UsedBy, DependsOn, Aliases } from './DependencyIndicator/DependencyIndicator'; import './KeyEditPage.css'; const Editor = ({ @@ -47,7 +47,8 @@ const Editor = ({ value={manifest.implementation.value} valueType={manifest.valueType} onChange={value => - onManifestChange({ ...manifest, implementation: { ...manifest.implementation, value } })} + onManifestChange({ ...manifest, implementation: { ...manifest.implementation, value } }) + } onValidationChange={onValidationChange} /> ); @@ -110,12 +111,13 @@ class KeyEditPage extends Component { }; render() { - const { selectedKey, isInStickyMode, alerter, revision } = this.props; + const { selectedKey, isInStickyMode, alerter, revision, deleteAlias } = this.props; const { key, local: { manifest, implementation }, revisionHistory, - dependentKeys, + usedBy, + aliases, } = selectedKey; const isHistoricRevision = revisionHistory && revision && revisionHistory[0].sha !== revision; const isReadonly = manifest.meta.readOnly || manifest.meta.archived || isHistoricRevision; @@ -141,7 +143,9 @@ class KeyEditPage extends Component { revision={revision} keyFullPath={key} isInStickyMode={isInStickyMode} - dependentKeys={dependentKeys} + usedBy={usedBy} + aliases={aliases} + deleteAlias={deleteAlias} />
@@ -173,11 +177,11 @@ const KeyStickyHeader = (props) => {
- {!isReadonly - ?
- -
- : null} + {!isReadonly ? ( +
+ +
+ ) : null}
); }; @@ -192,7 +196,9 @@ const KeyFullHeader = (props) => { keyFullPath, revision, isHistoricRevision, - dependentKeys, + usedBy, + aliases, + deleteAlias, } = props; return ( @@ -202,17 +208,15 @@ const KeyFullHeader = (props) => {
- {revisionHistory - ? - : null} + {revisionHistory ? ( + + ) : null}
- +
@@ -225,8 +229,9 @@ const KeyFullHeader = (props) => { classNames={{ input: 'description-input' }} maxLength={400} /> - + +
diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.less b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.less index 94b0bd706..f1f1a2587 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.less +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyEditPage.less @@ -55,43 +55,6 @@ .validation-message { font-size: 13px; } - .auto-suggest-wrapper { - display: flex; - flex-grow: 1; - flex-direction: row; - margin-bottom: 13px; - .override-typeahead(@text-padding) { - .bootstrap-typeahead-input-container { - display: flex; - flex-grow: 1; - .bootstrap-typeahead-input { - .key-name-input; - padding-left: @text-padding; - } - } - } - .override-typeahead(0); - &[data-with-error="true"] { - .override-typeahead(30px); - } - .validation-icon-wrapper { - flex-direction: row; - width: 0; - margin: 11px 0 0 0; - position: absolute; - z-index: 7; - .transitioned(); - &[data-is-shown="true"] { - width: 16px; - height: 16px; - margin-top: 5px; - padding: 3px 5px; - } - } - .auto-suggest { - flex-grow: 1; - } - } } } .sticky-key-header { diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.css b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.css index d08e6ad2c..deef7bdf3 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.css +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.css @@ -4,6 +4,8 @@ color: #888; } .key-action-buttons-wrapper { + display: flex; + align-items: center; float: right; } .key-action-buttons-wrapper .save-button { @@ -14,49 +16,24 @@ .key-action-buttons-wrapper .save-button[data-state-is-saving=true]:disabled { background-color: green; } -.key-action-buttons-wrapper .disable-button { - vertical-align: top; - background-color: #00aeef; +.key-action-buttons-wrapper .icon-button { + background-color: #bcbcbc; + margin-left: 10px; + width: 28px; height: 28px; - border: 0; - padding: 0 20px; - color: white; - outline: 0; - padding-bottom: 2px; - border-radius: 14px; - -moz-user-select: none; - -ms-user-select: none; - -webkit-user-select: none; - user-select: none; - transition: all 0.2s ease-in-out; - text-decoration: underline; - background-color: transparent; - color: gray; - width: 125px; -} -.key-action-buttons-wrapper .disable-button:hover { - background-color: #029CD5; + border-radius: 50%; + border: none; cursor: pointer; } -.key-action-buttons-wrapper .disable-button:disabled { - background-color: gray; -} -.key-action-buttons-wrapper .disable-button:disabled:hover, -.key-action-buttons-wrapper .disable-button:disabled:active { - cursor: default; - background-color: gray; -} -.key-action-buttons-wrapper .disable-button:hover { - background-color: rgba(0, 0, 0, 0.1); +.key-action-buttons-wrapper .icon-button:hover { + background-color: #9c9c9c; } -.key-action-buttons-wrapper .disable-button:active { - background-color: rgba(0, 0, 0, 0.2); +.key-action-buttons-wrapper .icon-button:active { + background-color: #7b7b7b; } -.key-action-buttons-wrapper .disable-button:disabled { - background-color: transparent; -} -.key-action-buttons-wrapper .disable-button:disabled:hover, -.key-action-buttons-wrapper .disable-button:disabled:active { +.key-action-buttons-wrapper .icon-button:disabled { cursor: default; - background-color: transparent; +} +.key-action-buttons-wrapper .icon-button img { + width: 28px; } diff --git a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.js b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.js index 6154e3650..5d00e68e7 100644 --- a/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.js +++ b/services/editor/src/pages/keys/components/KeyPage/KeyEditPage/KeyPageActions/KeyPageActions.js @@ -3,37 +3,88 @@ import { connect } from 'react-redux'; import { compose, mapProps } from 'recompose'; import * as R from 'ramda'; import * as keysActions from '../../../../../../store/ducks/selectedKey'; +import { showCustomAlert, buttons } from '../../../../../../store/ducks/alerts'; import SaveButton from '../../../../../../components/common/SaveButton/SaveButton'; +import NewKeyInput from '../../KeyAddPage/NewKeyInput'; +import archiveIcon from '../../../../../../resources/archive-icon.svg'; +import restoreIcon from '../../../../../../resources/restore-icon.svg'; +import trashIcon from '../../../../../../resources/trash-icon.svg'; +import linkIcon from '../../../../../../resources/link-icon.svg'; import './KeyPageActions.css'; -const disableButton = ({ text, dataComp }) => props => ( - ); -const DeleteButton = disableButton({ text: 'Delete key', dataComp: 'delete-key' }); -const ArchiveButton = disableButton({ text: 'Archive key', dataComp: 'archive-key' }); -const UnarchiveButton = disableButton({ text: 'Restore key', dataComp: 'unarchive-key' }); +const DeleteButton = iconButton({ image: trashIcon, text: 'Delete key', dataComp: 'delete-key' }); +const ArchiveButton = iconButton({ + image: archiveIcon, + text: 'Archive key', + dataComp: 'archive-key', +}); +const UnarchiveButton = iconButton({ + image: restoreIcon, + text: 'Restore key', + dataComp: 'unarchive-key', +}); +const AddAliasButton = iconButton({ image: linkIcon, text: 'Add Alias', dataComp: 'add-alias' }); const validationPath = ['selectedKey', 'validation', 'isValid']; const KeyPageActions = compose( - connect( - state => ({ selectedKey: state.selectedKey, isValid: R.path(validationPath, state) }), - keysActions, + connect(state => ({ selectedKey: state.selectedKey, isValid: R.path(validationPath, state) }), { + ...keysActions, + showCustomAlert, + }), + mapProps( + ({ + selectedKey: { key, local, remote, isSaving }, + isInStickyMode, + addAlias, + showCustomAlert, + ...props + }) => ({ + ...props, + hasChanges: !R.equals(local, remote), + isSaving, + extraButtons: !isInStickyMode, + archived: local && local.manifest.meta.archived, + addAlias: async () => { + const component = mapProps( + ({ onChange, componentData: { displayName = '', validation = {} } = {} }) => ({ + onChange: (newName, newValidation) => + onChange({ displayName: newName, validation: newValidation }), + displayName, + validation, + }), + )(NewKeyInput); + + const okButton = { + ...buttons.OK, + validate: data => data && data.validation.isValid, + }; + + const alert = { + title: `Add alias for ${key}`, + message: 'Insert a new alias', + component, + buttons: [okButton, buttons.CANCEL], + }; + + const alertResult = await showCustomAlert(alert); + if (alertResult.result && alertResult.data.validation.isValid) { + addAlias(alertResult.data.displayName); + } + }, + }), ), - mapProps(({ selectedKey: { key, local, remote, isSaving }, isInStickyMode, ...props }) => ({ - ...props, - hasChanges: !R.equals(local, remote), - isSaving, - extraButtons: !isInStickyMode, - archived: local && local.manifest.meta.archived, - })), )( ({ saveKey, deleteKey, + addAlias, isReadonly, isHistoricRevision, hasChanges, @@ -50,14 +101,14 @@ const KeyPageActions = compose(
) : null}
- {extraButtons && archived ? : null} - {extraButtons ? ( - archived ? ( + {extraButtons && archived && } + {extraButtons && + (archived ? ( archiveKey(false)} /> ) : ( archiveKey(true)} /> - ) - ) : null} + ))} + {extraButtons && } R.slice(0, -1, path.split('/')).join('/'); -const getSugesstions = R.pipe(R.map(getKeyPrefix), R.uniq(), R.filter(x => x !== '')); - -function getKeyNameSuggestions(keysList) { - return getSugesstions(keysList).sort(); -} - -const NewKeyInput = compose( - connect(state => ({ keysList: state.keys, keyNameValidation: state.selectedKey.validation.key })), - mapPropsStream((prop$) => { - const keysList$ = prop$ - .map(x => x.keysList) - .distinctUntilChanged() - .switchMap(SearchService.filterInternalKeys); - - return Observable.combineLatest(prop$, keysList$, (props, keysList) => ({ - ...props, - keysList, - })); - }), -)(({ keysList, keyNameValidation, onKeyNameChanged, displayName }) => { - const suggestions = getKeyNameSuggestions(keysList).map(x => ({ label: x, value: x })); - return ( -
- - onKeyNameChanged(text)} - showValueInOptions - /> -
- ); -}); - -NewKeyInput.displayName = 'NewKeyInput'; - -export default NewKeyInput; diff --git a/services/editor/src/resources/alert-icon.svg b/services/editor/src/resources/alert-icon.svg index 7b9c361b0..396dff144 100644 --- a/services/editor/src/resources/alert-icon.svg +++ b/services/editor/src/resources/alert-icon.svg @@ -1,15 +1,5 @@ - - - Alert Icon - Created with Sketch. - - -Layer 1 - - - - - - - - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/services/editor/src/resources/archive-icon.svg b/services/editor/src/resources/archive-icon.svg new file mode 100644 index 000000000..cada85fd6 --- /dev/null +++ b/services/editor/src/resources/archive-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/services/editor/src/resources/key-icon.svg b/services/editor/src/resources/key-icon.svg index 9522f0144..f3c605416 100644 --- a/services/editor/src/resources/key-icon.svg +++ b/services/editor/src/resources/key-icon.svg @@ -1,16 +1,9 @@ - - Key icon - Created with Sketch. - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/services/editor/src/resources/link-icon.svg b/services/editor/src/resources/link-icon.svg new file mode 100644 index 000000000..fa6edd5aa --- /dev/null +++ b/services/editor/src/resources/link-icon.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/services/editor/src/resources/restore-icon.svg b/services/editor/src/resources/restore-icon.svg new file mode 100644 index 000000000..b8b5553a0 --- /dev/null +++ b/services/editor/src/resources/restore-icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/services/editor/src/resources/trash-icon.svg b/services/editor/src/resources/trash-icon.svg new file mode 100644 index 000000000..df46500d5 --- /dev/null +++ b/services/editor/src/resources/trash-icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/services/editor/src/services/context-service.js b/services/editor/src/services/context-service.js index 221c1c909..64d27ee99 100644 --- a/services/editor/src/services/context-service.js +++ b/services/editor/src/services/context-service.js @@ -1,5 +1,5 @@ -/* global fetch */ import * as R from 'ramda'; +import fetch from '../utils/fetch'; import * as TypesService from './types-service'; export const KEYS_IDENTITY = 'keys.'; @@ -7,7 +7,7 @@ export const KEYS_IDENTITY = 'keys.'; let contextSchema = {}; export async function refreshSchema() { - const response = await fetch('/api/schemas', { credentials: 'same-origin' }); + const response = await fetch('/api/schemas'); contextSchema = await response.json(); } diff --git a/services/editor/src/services/types-service.js b/services/editor/src/services/types-service.js index 62dbea531..d98efdb05 100644 --- a/services/editor/src/services/types-service.js +++ b/services/editor/src/services/types-service.js @@ -1,4 +1,4 @@ -/* global fetch */ +import fetch from '../utils/fetch'; export const types = { string: { @@ -69,8 +69,13 @@ export async function getValueTypeDefinition(key) { if (!key || key.length === 0) return types.string; try { const response = await fetch(`/api/manifests/${key}`, { credentials: 'same-origin' }); - const meta = await response.json(); - return types[meta.valueType] || types.string; + const manifest = await response.json(); + + if (manifest.implementation.type === 'alias') { + return getValueTypeDefinition(manifest.implementation.key); + } + + return types[manifest.valueType] || types.string; } catch (err) { return types.string; } diff --git a/services/editor/src/store/ducks/alerts.js b/services/editor/src/store/ducks/alerts.js index 2c6523cc1..1719c5746 100644 --- a/services/editor/src/store/ducks/alerts.js +++ b/services/editor/src/store/ducks/alerts.js @@ -5,7 +5,7 @@ const chance = new Chance(); const ADD_ALERT = 'ADD_ALERT'; const REMOVE_ALERT = 'REMOVE_ALERT'; -const buttons = { +export const buttons = { OK: { text: 'OK', value: true, @@ -25,8 +25,8 @@ export function showCustomAlert({ buttons, ...alertProps }) { dispatch( new Promise((resolve) => { const id = chance.guid(); - const onClose = (result) => { - resolve({ type: REMOVE_ALERT, id, result }); + const onClose = (result, data) => { + resolve({ type: REMOVE_ALERT, id, result, data }); }; const alert = { @@ -35,7 +35,7 @@ export function showCustomAlert({ buttons, ...alertProps }) { onClose: () => onClose(), buttons: buttons.map(({ value, ...props }) => ({ ...props, - onClick: () => onClose(value), + onClick: data => onClose(value, data), })), }; dispatch({ type: ADD_ALERT, alert }); diff --git a/services/editor/src/store/ducks/ducks-utils/blankKeyDefinition.js b/services/editor/src/store/ducks/ducks-utils/blankKeyDefinition.js index f28f7e7e6..eb8840668 100644 --- a/services/editor/src/store/ducks/ducks-utils/blankKeyDefinition.js +++ b/services/editor/src/store/ducks/ducks-utils/blankKeyDefinition.js @@ -1,18 +1,25 @@ export const BLANK_KEY_NAME = '_blank'; export function createBlankKeyManifest(keyName, implementation = { type: 'file', format: 'jpad' }) { - return { + const manifest = { meta: { - name: '', - tags: [], - description: '', archived: false, }, implementation, - valueType: '', - dependencies: [], - enabled: true, }; + + if (implementation.type !== 'alias') { + manifest.valueType = 'string'; + manifest.dependencies = []; + manifest.meta = { + ...manifest.meta, + name: keyName, + description: '', + tags: [], + }; + } + + return manifest; } export function createJPadSource(valueType = '', rules = [], partitions = []) { @@ -33,18 +40,3 @@ export function createBlankJPadKey() { key: BLANK_KEY_NAME, }; } - -export function createBlankKey() { - return { - implementation: { - source: '', - type: '', - valueType: '', - }, - manifest: createBlankKeyManifest('', { - type: '', - format: '', - }), - key: BLANK_KEY_NAME, - }; -} diff --git a/services/editor/src/store/ducks/selectedKey.js b/services/editor/src/store/ducks/selectedKey.js index d4e4338cb..d04371fa7 100644 --- a/services/editor/src/store/ducks/selectedKey.js +++ b/services/editor/src/store/ducks/selectedKey.js @@ -9,7 +9,6 @@ import { createBlankKeyManifest, BLANK_KEY_NAME, } from './ducks-utils/blankKeyDefinition'; -import keyNameValidations from './ducks-utils/validations/key-name-validations'; import keyValueTypeValidations from './ducks-utils/validations/key-value-type-validations'; import { continueGuard } from './ducks-utils/guards'; import { downloadTags } from './tags'; @@ -28,7 +27,7 @@ const KEY_SAVED = 'KEY_SAVED'; const KEY_SAVING = 'KEY_SAVING'; const KEY_NAME_CHANGE = 'KEY_NAME_CHANGE'; const KEY_REVISION_HISTORY = 'KEY_REVISION_HISTORY'; -const DEPENDENT_KEYS = 'DEPENDENT_KEYS'; +const KEY_DEPENDENTS = 'KEY_DEPENDENTS'; const KEY_VALIDATION_CHANGE = 'KEY_VALIDATION_CHANGE'; const KEY_VALUE_TYPE_CHANGE = 'KEY_VALUE_TYPE_CHANGE'; const SHOW_KEY_VALIDATIONS = 'SHOW_KEY_VALIDATIONS'; @@ -53,20 +52,20 @@ function updateRevisionHistory(keyName) { }; } -function updateDependentKeys(keyName) { +function updateKeyDependents(keyName) { return async function (dispatch) { - let dependentKeys = []; + let dependents = {}; try { - dependentKeys = await (await fetch(`/api/dependents/${keyName}`)).json(); + dependents = await (await fetch(`/api/dependents/${keyName}`)).json(); } catch (error) { dispatch( showError({ - title: `Failed to enumerate keys dependent on ${keyName}`, + title: `Failed to enumerate key dependents on ${keyName}`, error, }), ); } - dispatch({ type: DEPENDENT_KEYS, payload: { keyName, dependentKeys } }); + dispatch({ type: KEY_DEPENDENTS, payload: { keyName, ...dependents } }); }; } @@ -121,7 +120,7 @@ export function openKey(key, { revision } = {}) { return async function (dispatch) { dispatch(downloadTags()); try { - ContextService.refreshSchema(); + await ContextService.refreshSchema(); } catch (error) { dispatch(showError({ title: 'Failed to refresh schema', error })); } @@ -145,6 +144,11 @@ export function openKey(key, { revision } = {}) { } const manifest = keyData.manifest || createBlankKeyManifest(key); + if (manifest.implementation.type === 'alias') { + dispatch(push(`/keys/${manifest.implementation.key}`)); + return; + } + const implementation = createImplementation(keyData); const keyOpenedPayload = { key, @@ -154,7 +158,7 @@ export function openKey(key, { revision } = {}) { await dispatch({ type: KEY_OPENED, payload: keyOpenedPayload }); dispatch(updateRevisionHistory(key)); - dispatch(updateDependentKeys(key)); + dispatch(updateKeyDependents(key)); }; } @@ -214,6 +218,7 @@ export function archiveKey(archived) { dispatch(addKeyToList(key)); } dispatch(updateRevisionHistory(key)); + dispatch(updateKeyDependents(key)); }; } @@ -247,30 +252,24 @@ export function changeKeyValueType(keyValueType) { }; } -export function updateKeyPath(newKeyPath) { - return async function (dispatch) { - await dispatch(updateKeyName(newKeyPath)); - dispatch({ type: KEY_PATH_CHANGE, payload: newKeyPath }); - }; -} - -export function updateKeyName(newKeyName) { +export function updateKeyPath(newKeyPath, validation) { return async function (dispatch, getState) { - const keyNameValidation = keyNameValidations(newKeyName, getState().keys); - keyNameValidation.isShowingHint = !keyNameValidation.isValid; - - dispatch({ type: KEY_NAME_CHANGE, payload: newKeyName }); - const currentValidationState = getState().selectedKey.validation; const newValidation = { ...currentValidationState, - key: keyNameValidation, + key: validation, }; dispatch({ type: KEY_VALIDATION_CHANGE, payload: newValidation }); + dispatch({ type: KEY_PATH_CHANGE, payload: newKeyPath }); + dispatch(updateKeyName(newKeyPath)); }; } +export function updateKeyName(newKeyName) { + return { type: KEY_NAME_CHANGE, payload: newKeyName }; +} + export function saveKey() { return async function (dispatch, getState) { const currentState = getState(); @@ -286,7 +285,7 @@ export function saveKey() { if (!await performSave(dispatch, savedKey, local)) return; dispatch(updateRevisionHistory(savedKey)); - dispatch(updateDependentKeys(savedKey)); + dispatch(updateKeyDependents(savedKey)); if (isNewKey) { dispatch(addKeyToList(savedKey)); @@ -295,33 +294,84 @@ export function saveKey() { }; } -const deleteKeyAlert = key => ({ +const deleteKeyAlert = (key, aliases = []) => ({ title: 'Warning', - message: `Are you sure you want to delete '${key}' key?`, + message: `Are you sure you want to delete '${key}'?${ + aliases.length ? `\nAll aliases will also be deleted:\n${aliases.join('\n')}` : '' + }`, }); export function deleteKey() { return async function (dispatch, getState) { - const { selectedKey: { key } } = getState(); + const { selectedKey: { key, aliases } } = getState(); - if (!(await dispatch(showConfirm(deleteKeyAlert(key)))).result) return; + if (!(await dispatch(showConfirm(deleteKeyAlert(key, aliases)))).result) return; dispatch(push('/keys')); try { await fetch(`/api/keys/${key}`, { method: 'delete', + ...withJsonData(aliases), }); dispatch(removeKeyFromList(key)); + aliases.forEach(alias => dispatch(removeKeyFromList(alias))); } catch (error) { dispatch(showError({ title: 'Failed to delete key!', error })); } }; } +export function addAlias(alias) { + return async function (dispatch, getState) { + const { selectedKey: { key } } = getState(); + + const manifest = createBlankKeyManifest(alias, { type: 'alias', key }); + + try { + await fetch(`/api/keys/${alias}`, { + method: 'put', + ...withJsonData({ manifest }), + }); + } catch (error) { + dispatch(showError({ title: 'Failed to add alias', error })); + return; + } + + dispatch(addKeyToList(alias)); + + const { selectedKey: { usedBy, aliases } } = getState(); + dispatch({ + type: KEY_DEPENDENTS, + payload: { keyName: key, usedBy, aliases: aliases.concat(alias) }, + }); + }; +} + +export function deleteAlias(alias) { + return async function (dispatch, getState) { + if (!(await dispatch(showConfirm(deleteKeyAlert(alias)))).result) return; + + try { + await fetch(`/api/keys/${alias}`, { method: 'delete' }); + + dispatch(removeKeyFromList(alias)); + const { selectedKey: { key, usedBy, aliases } } = getState(); + const aliasIndex = aliases.indexOf(alias); + if (aliasIndex >= 0) { + dispatch({ + type: KEY_DEPENDENTS, + payload: { keyName: key, usedBy, aliases: R.remove(aliasIndex, 1, aliases) }, + }); + } + } catch (error) { + dispatch(showError({ title: 'Failed to delete alias!', error })); + } + }; +} + const setValidationHintsVisibility = (validationState, isShown) => { - Object.keys(validationState) - .map(x => validationState[x]) + Object.values(validationState) .filter(x => typeof x === 'object') .map((x) => { setValidationHintsVisibility(x, isShown); @@ -344,7 +394,6 @@ const handleKeyOpened = (state, { payload: { key, ...keyData } }) => { detailsAdded = true; } else { validation = { - key: keyNameValidations(key, []), manifest: { valueType: keyValueTypeValidations(keyData.manifest.valueType), }, @@ -415,8 +464,7 @@ const handleKeyNameChange = ({ local: { key, ...localData }, ...otherState }, { }); const isStateInvalid = validationState => - Object.keys(validationState) - .map(x => validationState[x]) + Object.values(validationState) .filter(x => typeof x === 'object') .some(x => x.isValid === false || isStateInvalid(x)); @@ -462,11 +510,12 @@ const handleKeyRevisionHistory = (state, { payload: { keyName, revisionHistory } }; }; -const handleDependentKeys = (state, { payload: { keyName, dependentKeys } }) => { +const handleKeyDependents = (state, { payload: { keyName, usedBy, aliases } }) => { if (state.key !== keyName) return state; return { ...state, - dependentKeys, + usedBy, + aliases, }; }; @@ -519,7 +568,7 @@ export default handleActions( [KEY_VALUE_TYPE_CHANGE]: handleKeyValueTypeChange, [KEY_REVISION_HISTORY]: handleKeyRevisionHistory, [SHOW_KEY_VALIDATIONS]: handleShowKeyValidations, - [DEPENDENT_KEYS]: handleDependentKeys, + [KEY_DEPENDENTS]: handleKeyDependents, [KEY_CLOSED]: () => null, }, null, diff --git a/services/editor/yarn.lock b/services/editor/yarn.lock index f03af0ba9..1fe7468ee 100644 --- a/services/editor/yarn.lock +++ b/services/editor/yarn.lock @@ -25,6 +25,13 @@ dependencies: "@babel/types" "7.0.0-beta.31" +"@babel/helper-module-imports@7.0.0-beta.32": + version "7.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.32.tgz#8126fc024107c226879841b973677a4f4e510a03" + dependencies: + "@babel/types" "7.0.0-beta.32" + lodash "^4.2.0" + "@babel/template@7.0.0-beta.31": version "7.0.0-beta.31" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda" @@ -55,6 +62,14 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +"@babel/types@7.0.0-beta.32": + version "7.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.32.tgz#c317d0ecc89297b80bbcb2f50608e31f6452a5ff" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + "@types/autosize@3.0.6": version "3.0.6" resolved "https://registry.yarnpkg.com/@types/autosize/-/autosize-3.0.6.tgz#9022e6a783ec5a4d5e570013701dbc0bfe7667fa" @@ -669,6 +684,12 @@ babel-loader@7.1.2, babel-loader@^7.1.2: loader-utils "^1.0.2" mkdirp "^0.5.1" +babel-macros@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/babel-macros/-/babel-macros-1.2.0.tgz#39e47ed6d286d4a98f1948d8bab45dac17e4e2d4" + dependencies: + cosmiconfig "3.1.0" + babel-messages@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" @@ -689,6 +710,19 @@ babel-plugin-dynamic-import-node@1.1.0: babel-template "^6.26.0" babel-types "^6.26.0" +babel-plugin-emotion@^8.0.12: + version "8.0.12" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-8.0.12.tgz#2ed844001416b0ae2ff787a06b1804ec5f531c89" + dependencies: + "@babel/helper-module-imports" "7.0.0-beta.32" + babel-macros "^1.2.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + emotion-utils "^8.0.12" + find-root "^1.1.0" + source-map "^0.5.7" + touch "^1.0.0" + babel-plugin-istanbul@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-2.0.3.tgz#266b304b9109607d60748474394676982f660df4" @@ -762,7 +796,7 @@ babel-plugin-syntax-function-bind@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: +babel-plugin-syntax-jsx@^6.18.0, babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -2019,6 +2053,15 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cosmiconfig@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^3.0.0" + require-from-string "^2.0.1" + cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: version "2.2.2" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892" @@ -2276,6 +2319,10 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + deep-eql@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -2585,6 +2632,19 @@ emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" +emotion-utils@^8.0.12: + version "8.0.12" + resolved "https://registry.yarnpkg.com/emotion-utils/-/emotion-utils-8.0.12.tgz#5e0fd72db3008f26ce4f80b1972df08841df2168" + +emotion@8.0.12: + version "8.0.12" + resolved "https://registry.yarnpkg.com/emotion/-/emotion-8.0.12.tgz#03de11ce26b1b2401c334b94d438652124c514c6" + dependencies: + babel-plugin-emotion "^8.0.12" + emotion-utils "^8.0.12" + stylis "^3.3.2" + stylis-rule-sheet "^0.0.5" + encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" @@ -2614,7 +2674,7 @@ errno@^0.1.1, errno@^0.1.3, errno@^0.1.4: dependencies: prr "~0.0.0" -error-ex@^1.2.0: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: @@ -2857,9 +2917,9 @@ eslint@4.10.0: table "^4.0.1" text-table "~0.2.0" -eslint@^4.12.1: - version "4.12.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.1.tgz#5ec1973822b4a066b353770c3c6d69a2a188e880" +eslint@^4.13.1: + version "4.13.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f" dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -2989,9 +3049,9 @@ exec-sh@^0.2.0: dependencies: merge "^1.1.3" -execa@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -3261,6 +3321,10 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + find-up@^1.0.0, find-up@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -4806,7 +4870,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.9.1: +js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.9.0, js-yaml@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: @@ -5496,9 +5560,9 @@ moment@^2.10.6: version "2.19.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.2.tgz#8a7f774c95a64550b4c7ebd496683908f9419dbe" -moment@^2.19.3: - version "2.19.3" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.3.tgz#bdb99d270d6d7fda78cc0fbace855e27fe7da69f" +moment@^2.19.4: + version "2.19.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.4.tgz#17e5e2c6ead8819c8ecfad83a0acccb312e94682" monaco-editor@^0.10.0: version "0.10.1" @@ -5962,6 +6026,12 @@ parse-json@^2.1.0, parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13" + dependencies: + error-ex "^1.3.1" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -5981,7 +6051,7 @@ pascal-case@^2.0.0: camel-case "^3.0.0" upper-case-first "^1.1.0" -passport-azure-ad@^3.0.6: +passport-azure-ad@^3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/passport-azure-ad/-/passport-azure-ad-3.0.8.tgz#efddf32078506d267f9229f3abbc4dec8cbf2078" dependencies: @@ -6587,6 +6657,14 @@ qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +query-string@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.0.1.tgz#6e2b86fe0e08aef682ecbe86e85834765402bd88" + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + query-string@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -6666,9 +6744,9 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-autosize-textarea@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/react-autosize-textarea/-/react-autosize-textarea-1.0.1.tgz#4d06635e8f1c6d343eecdfa82515676fb6ec9e16" +react-autosize-textarea@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-autosize-textarea/-/react-autosize-textarea-1.0.2.tgz#9d2ff8c467dfbbc42a76fd7878db3c62f9ecf1c8" dependencies: "@types/autosize" "3.0.6" "@types/prop-types" "15.5.2" @@ -6727,7 +6805,6 @@ react-document-title@2.0.3: react-dom@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" - dependencies: fbjs "^0.8.16" loose-envify "^1.1.0" @@ -6741,6 +6818,13 @@ react-draggable@^3.0.4: classnames "^2.2.5" prop-types "^15.6.0" +react-emotion@8.0.12: + version "8.0.12" + resolved "https://registry.yarnpkg.com/react-emotion/-/react-emotion-8.0.12.tgz#3dd94c151197e2e3399e34e3e118df141b5ebb7b" + dependencies: + babel-plugin-emotion "^8.0.12" + emotion-utils "^8.0.12" + react-error-overlay@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-3.0.0.tgz#c2bc8f4d91f1375b3dad6d75265d51cd5eeaf655" @@ -6756,9 +6840,9 @@ react-highlight-words@^0.10.0: highlight-words-core "^1.1.0" prop-types "^15.5.8" -react-monaco-editor@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.12.0.tgz#d96fbb07eb743eb4ad10b69d80f9985416f1a266" +react-monaco-editor@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.13.0.tgz#efb4c45191119bdbbdcbd4de0ff1705b7af929ed" dependencies: monaco-editor "^0.10.0" prop-types "^15.5.10" @@ -6771,7 +6855,7 @@ react-notification-system@^0.2.16: object-assign "^4.0.1" prop-types "^15.5.6" -react-redux@^5.0.5: +react-redux@^5.0.6: version "5.0.6" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946" dependencies: @@ -6864,7 +6948,6 @@ react-scripts@1.0.17: optionalDependencies: fsevents "1.1.2" - react-side-effect@^1.0.2: version "1.1.3" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.3.tgz#512c25abe0dec172834c4001ec5c51e04d41bc5c" @@ -6929,15 +7012,6 @@ react-virtualized@^9.13.0: loose-envify "^1.3.0" prop-types "^15.5.4" -react@^16.0.0: - version "16.1.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.1.1.tgz#d5c4ef795507e3012282dd51261ff9c0e824fe1f" - dependencies: - fbjs "^0.8.16" - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.0" - react@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" @@ -7054,7 +7128,7 @@ reduce-reducers@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.1.2.tgz#fa1b4718bc5292a71ddd1e5d839c9bea9770f14b" -redux-actions@^2.0.3: +redux-actions@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/redux-actions/-/redux-actions-2.2.1.tgz#d64186b25649a13c05478547d7cd7537b892410d" dependencies: @@ -7073,7 +7147,7 @@ redux-thunk@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5" -redux@^3.6.0, redux@^3.7.1: +redux@^3.7.1, redux@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b" dependencies: @@ -7245,6 +7319,10 @@ require-from-string@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" +require-from-string@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff" + require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -7327,12 +7405,9 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^2.0.0" inherits "^2.0.1" -rodal@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/rodal/-/rodal-1.6.1.tgz#6633f10bcddfd49e21f5e678343a86185c3838d7" - dependencies: - prop-types "^15.6.0" - react "^16.0.0" +rodal@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/rodal/-/rodal-1.6.3.tgz#27c4810ca2d34fd6aedcbdbf7721a06c78a5b9a8" run-async@^2.2.0: version "2.3.0" @@ -7354,11 +7429,11 @@ rx@2.3.24: version "2.3.24" resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" -rxjs@^5.5.3: - version "5.5.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.3.tgz#b62227e74b84f4e77bdf440e50b5ee01a1bc7dcd" +rxjs@^5.5.5: + version "5.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.5.tgz#e164f11d38eaf29f56f08c3447f74ff02dd84e97" dependencies: - symbol-observable "^1.0.1" + symbol-observable "1.0.1" safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" @@ -7602,7 +7677,7 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" -source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.6: +source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -7813,6 +7888,14 @@ style-loader@0.19.0: loader-utils "^1.0.2" schema-utils "^0.3.0" +stylis-rule-sheet@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.5.tgz#ebae935cc1f6fb31b9b62dba47f2ea8b833dad9f" + +stylis@^3.3.2: + version "3.4.5" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.4.5.tgz#d7b9595fc18e7b9c8775eca8270a9a1d3e59806e" + supports-color@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" @@ -7882,7 +7965,11 @@ swap-case@^1.1.0: lower-case "^1.1.1" upper-case "^1.1.1" -symbol-observable@^1.0.1, symbol-observable@^1.0.3, symbol-observable@^1.0.4: +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +symbol-observable@^1.0.3, symbol-observable@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" @@ -8023,6 +8110,12 @@ toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" +touch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de" + dependencies: + nopt "~1.0.10" + touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" diff --git a/services/git-service/BareRepository/Dockerfile b/services/git-service/BareRepository/Dockerfile index b53d14436..2b33183b1 100644 --- a/services/git-service/BareRepository/Dockerfile +++ b/services/git-service/BareRepository/Dockerfile @@ -1,34 +1,33 @@ -FROM alpine:3.4 - -RUN apk add --no-cache \ - openssh \ - git \ - bash \ - curl - -RUN ssh-keygen -A +FROM alpine:3.7 + +RUN apk add --no-cache openssh git bash curl && \ + ssh-keygen -A && \ + adduser -D -s /usr/bin/git-shell git && \ + echo git:12345 | chpasswd && \ + mkdir /home/git/.ssh && \ + git config --global user.email "git@tweek" && \ + git config --global user.name "git" && \ + mkdir /tweek && mkdir /tweek/repo && mkdir /tweek/tests && \ + cd /tweek/repo && git init --bare && \ + cd /tweek/tests && git init --bare WORKDIR /tweek +COPY sshd_config /etc/ssh/sshd_config +COPY init.sh init.sh +COPY source ./source +COPY tests-source ./tests-source -RUN adduser -D -s /usr/bin/git-shell git \ - && echo git:12345 | chpasswd \ - && mkdir /home/git/.ssh +RUN cd ./source && \ + git init && git add . && git commit -m "init" && git push ../repo master && \ + cd - && rm -rf source && \ + cd ./tests-source && \ + git init && git add . && git commit -m "init" && git push ../tests master && \ + cd - && rm -rf tests-source -COPY source /tweek/source -COPY tests-source /tweek/tests-source -RUN git config --global user.email "git@tweek" -RUN git config --global user.name "git" -RUN mkdir repo && cd repo && git init --bare -RUN mkdir tests && cd tests && git init --bare -RUN cd ./source && git init && git add . && git commit -m "init" && git push ../repo master -RUN cd ./tests-source && git init && git add . && git commit -m "init" && git push ../tests master COPY pre-receive.sh /tweek/repo/hooks/pre-receive COPY pre-receive.sh /tweek/tests/hooks/pre-receive VOLUME /tweek/repo -COPY sshd_config /etc/ssh/sshd_config -COPY init.sh init.sh - EXPOSE 22 CMD ["sh", "init.sh"] diff --git a/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/read_configuration.json b/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/read_configuration.json index 2b0a5e8f1..693b016b5 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/read_configuration.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/read_configuration.json @@ -11,6 +11,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/write_context.json b/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/write_context.json index 9ad993ef6..f2c283255 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/write_context.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/auth/@global/write_context.json @@ -11,6 +11,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/auth/tweek_editor_user/write_context.json b/services/git-service/BareRepository/source/manifests/@tweek/auth/tweek_editor_user/write_context.json index 225c51810..5234010a9 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/auth/tweek_editor_user/write_context.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/auth/tweek_editor_user/write_context.json @@ -12,6 +12,5 @@ "value": false }, "valueType": "boolean", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/custom_types/version.json b/services/git-service/BareRepository/source/manifests/@tweek/custom_types/version.json index b80eb68bb..ef2acc86e 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/custom_types/version.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/custom_types/version.json @@ -15,6 +15,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/enabled.json b/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/enabled.json index 9d45a4a33..6e7cb4031 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/enabled.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/enabled.json @@ -11,6 +11,5 @@ "value": false }, "valueType": "boolean", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/id.json b/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/id.json index 252d521df..3536752a3 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/id.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/editor/google_tag_manager/id.json @@ -11,6 +11,5 @@ "value": "" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/editor/history/since.json b/services/git-service/BareRepository/source/manifests/@tweek/editor/history/since.json index d7c650364..e00f2e270 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/editor/history/since.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/editor/history/since.json @@ -12,6 +12,5 @@ "value": "1 month ago" }, "valueType": "string", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/editor/search/max_results.json b/services/git-service/BareRepository/source/manifests/@tweek/editor/search/max_results.json index 0f3a768ba..d61f10b0b 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/editor/search/max_results.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/editor/search/max_results.json @@ -12,6 +12,5 @@ "value": 25 }, "valueType": "number", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/editor/service_worker/is_enabled.json b/services/git-service/BareRepository/source/manifests/@tweek/editor/service_worker/is_enabled.json index b1982453a..15043e3af 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/editor/service_worker/is_enabled.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/editor/service_worker/is_enabled.json @@ -12,6 +12,5 @@ "value": false }, "valueType": "boolean", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/editor/show_internal_keys.json b/services/git-service/BareRepository/source/manifests/@tweek/editor/show_internal_keys.json index b407b061b..705f6183d 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/editor/show_internal_keys.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/editor/show_internal_keys.json @@ -12,6 +12,5 @@ "value": false }, "valueType": "boolean", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/source/manifests/@tweek/schema/user.json b/services/git-service/BareRepository/source/manifests/@tweek/schema/user.json index 78a4c4bd0..b940ba463 100644 --- a/services/git-service/BareRepository/source/manifests/@tweek/schema/user.json +++ b/services/git-service/BareRepository/source/manifests/@tweek/schema/user.json @@ -32,6 +32,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/sshd_config b/services/git-service/BareRepository/sshd_config index 2e8db3293..6129ea44d 100644 --- a/services/git-service/BareRepository/sshd_config +++ b/services/git-service/BareRepository/sshd_config @@ -46,7 +46,6 @@ #MaxAuthTries 6 #MaxSessions 10 -RSAAuthentication yes PubkeyAuthentication yes # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/behavior_tests/dependent_keys/display/depends_on_alias.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/behavior_tests/dependent_keys/display/depends_on_alias.jpad new file mode 100644 index 000000000..4d7fa252f --- /dev/null +++ b/services/git-service/BareRepository/tests-source/implementations/jpad/behavior_tests/dependent_keys/display/depends_on_alias.jpad @@ -0,0 +1,13 @@ +{ + "partitions": [], + "valueType": "string", + "rules": [ + { + "Matcher": { + "keys.behavior_tests/dependent_keys/display/alias_key": "value" + }, + "Value": "value", + "Type": "SingleVariant" + } + ] +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/identity_context/color.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/identity_context/color.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/identity_context/color.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/identity_context/color.jpad diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/comparison.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/comparison.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/comparison.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/comparison.jpad diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/in.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/in.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/in.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/in.jpad diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/multi_conditions.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/multi_conditions.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/multi_conditions.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/multi_conditions.jpad diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/simple.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/simple.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/rule_based_keys/simple.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/rule_based_keys/simple.jpad diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/value_distribution/bernoulli.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/value_distribution/bernoulli.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/value_distribution/bernoulli.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/value_distribution/bernoulli.jpad diff --git a/services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/value_distribution/weighted_normalized.jpad b/services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/value_distribution/weighted_normalized.jpad similarity index 100% rename from services/git-service/BareRepository/tests-source/implementations/jpad/@smoke_tests/value_distribution/weighted_normalized.jpad rename to services/git-service/BareRepository/tests-source/implementations/jpad/smoke_tests/value_distribution/weighted_normalized.jpad diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/read_configuration.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/read_configuration.json index 2b0a5e8f1..693b016b5 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/read_configuration.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/read_configuration.json @@ -11,6 +11,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/write_context.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/write_context.json index 9ad993ef6..f2c283255 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/write_context.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/@global/write_context.json @@ -11,6 +11,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/tweek_editor_user/write_context.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/tweek_editor_user/write_context.json index 225c51810..5234010a9 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/tweek_editor_user/write_context.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/auth/tweek_editor_user/write_context.json @@ -12,6 +12,5 @@ "value": false }, "valueType": "boolean", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/custom_types/version.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/custom_types/version.json index 1dfa534cf..ba9186253 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/custom_types/version.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/custom_types/version.json @@ -15,6 +15,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/enabled.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/enabled.json index cb982adba..83a82657a 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/enabled.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/enabled.json @@ -11,6 +11,5 @@ "format": "jpad" }, "valueType": "boolean", - "dependencies": [], - "enabled": true + "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/id.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/id.json index 3c1d589ae..25d70b263 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/id.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/google_tag_manager/id.json @@ -11,6 +11,5 @@ "format": "jpad" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/history/since.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/history/since.json index d7c650364..e00f2e270 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/history/since.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/history/since.json @@ -12,6 +12,5 @@ "value": "1 month ago" }, "valueType": "string", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/search/max_results.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/search/max_results.json index 0f3a768ba..d61f10b0b 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/search/max_results.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/search/max_results.json @@ -12,6 +12,5 @@ "value": 25 }, "valueType": "number", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/service_worker/is_enabled.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/service_worker/is_enabled.json index 518c180b9..1999fcb9c 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/service_worker/is_enabled.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/service_worker/is_enabled.json @@ -12,6 +12,5 @@ "value": false }, "valueType": "boolean", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/show_internal_keys.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/show_internal_keys.json index b407b061b..705f6183d 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/show_internal_keys.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/editor/show_internal_keys.json @@ -12,6 +12,5 @@ "value": false }, "valueType": "boolean", - "enabled": true, "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/delete_property_test.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/delete_property_test.json index 6c083d1cd..e2f0dbd75 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/delete_property_test.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/delete_property_test.json @@ -14,6 +14,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/edit_properties_test.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/edit_properties_test.json index 5de11e3b4..e844ec404 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/edit_properties_test.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/edit_properties_test.json @@ -14,6 +14,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/other.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/other.json index 9c0b3214a..c217438f5 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/other.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/other.json @@ -14,6 +14,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/user.json b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/user.json index 99b16befe..a8bba74cf 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/user.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek/schema/user.json @@ -35,6 +35,5 @@ } }, "valueType": "object", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key1.json b/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key1.json index 64fb03496..2bdfa41e6 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key1.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key1.json @@ -15,6 +15,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key2.json b/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key2.json index b03d27821..462e18213 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key2.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category/test_key2.json @@ -15,6 +15,5 @@ "format": "jpad" }, "valueType": "boolean", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category2/user_fruit.json b/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category2/user_fruit.json index 00f2b8319..a5c551b10 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category2/user_fruit.json +++ b/services/git-service/BareRepository/tests-source/manifests/@tweek_clients_tests/test_category2/user_fruit.json @@ -15,6 +15,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/context/override_key.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/context/override_key.json index 7fcf0b3bc..ed0368404 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/context/override_key.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/context/override_key.json @@ -11,6 +11,5 @@ "value": 0 }, "valueType": "number", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/archive.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/archive.json index da6c3791a..f56be7d95 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/archive.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/archive.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/accepted.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/accepted.json index b7509276b..048de8e1c 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/accepted.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/accepted.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/alias.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/alias.json new file mode 100644 index 000000000..e43202548 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/alias.json @@ -0,0 +1,10 @@ +{ + "key_path": "behavior_tests/delete_key/delete/alias", + "meta": { + "archived": false + }, + "implementation": { + "type": "alias", + "key": "behavior_tests/delete_key/delete/accepted" + } +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/canceled.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/canceled.json index 601360ef2..94902f827 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/canceled.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/canceled.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/not_accepted.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/not_accepted.json index 635a895b1..c19a4fc0d 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/not_accepted.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/delete/not_accepted.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/unarchive.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/unarchive.json index 66fef2c96..c9f310251 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/unarchive.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/delete_key/unarchive.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/alias_key.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/alias_key.json new file mode 100644 index 000000000..d6ab903c4 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/alias_key.json @@ -0,0 +1,10 @@ +{ + "key_path": "behavior_tests/dependent_keys/display/alias_key", + "meta": { + "archived": false + }, + "implementation": { + "type": "alias", + "key": "behavior_tests/dependent_keys/display/used_by" + } +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on.json index f8007b575..8da8bccaa 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on.json @@ -12,7 +12,6 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [ "behavior_tests/dependent_keys/display/used_by" ] diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on_alias.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on_alias.json new file mode 100644 index 000000000..505eac697 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/depends_on_alias.json @@ -0,0 +1,18 @@ +{ + "key_path": "behavior_tests/dependent_keys/display/depends_on_alias", + "meta": { + "name": "behavior_tests/dependent_keys/display/depends_on_alias", + "description": "", + "tags": [], + "readOnly": false, + "archived": false + }, + "implementation": { + "type": "file", + "format": "jpad" + }, + "valueType": "string", + "dependencies": [ + "behavior_tests/dependent_keys/display/alias_key" + ] +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/used_by.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/used_by.json index 9e69ab649..c2d459909 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/used_by.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/display/used_by.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/first.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/first.json index 20a3ec2c4..a027704d8 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/first.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/first.json @@ -12,7 +12,6 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [ "behavior_tests/dependent_keys/fail/second" ] diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/second.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/second.json index 74c5e0148..ac0b9f367 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/second.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/second.json @@ -12,7 +12,6 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [ "behavior_tests/dependent_keys/fail/third" ] diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/third.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/third.json index 24d03c0ae..4b50de62a 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/third.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/fail/third.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/depends_on.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/depends_on.json index d5e76bb7a..aa6a0da03 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/depends_on.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/depends_on.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/used_by.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/used_by.json index 9943cc1d5..6c1a7c285 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/used_by.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/dependent_keys/pass/used_by.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/text/edit_test.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/text/edit_test.json index 2948729b0..fcc969e9d 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/text/edit_test.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/text/edit_test.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/number_type.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/number_type.json index cb9a5bc08..e19277660 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/number_type.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/number_type.json @@ -11,6 +11,5 @@ "value": 10 }, "valueType": "number", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/object_type.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/object_type.json index 49ac2de1d..8a9603a32 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/object_type.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/object_type.json @@ -13,6 +13,5 @@ } }, "valueType": "object", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/string_type.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/string_type.json index cfe658234..ad5c746dc 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/string_type.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/const/string_type.json @@ -11,6 +11,5 @@ "value": "hello" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/edit_test.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/edit_test.json index fe3bbe5c7..ac02268a7 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/edit_test.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/edit_key/visual/edit_test.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_key.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_key.json new file mode 100644 index 000000000..69ca1c14e --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_key.json @@ -0,0 +1,10 @@ +{ + "key_path": "behavior_tests/key_aliases/alias_key", + "meta": { + "archived": false + }, + "implementation": { + "type": "alias", + "key": "behavior_tests/key_aliases/regular_key" + } +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_to_alias.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_to_alias.json new file mode 100644 index 000000000..4493d6522 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/alias_to_alias.json @@ -0,0 +1,10 @@ +{ + "key_path": "behavior_tests/key_aliases/alias_to_alias", + "meta": { + "archived": false + }, + "implementation": { + "type": "alias", + "key": "behavior_tests/key_aliases/alias_key" + } +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/delete_alias.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/delete_alias.json new file mode 100644 index 000000000..09cc1ef58 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/delete_alias.json @@ -0,0 +1,10 @@ +{ + "key_path": "behavior_tests/key_aliases/delete_alias", + "meta": { + "archived": false + }, + "implementation": { + "type": "alias", + "key": "behavior_tests/key_aliases/regular_key" + } +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/regular_key.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/regular_key.json new file mode 100644 index 000000000..17799fec6 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/key_aliases/regular_key.json @@ -0,0 +1,15 @@ +{ + "key_path": "behavior_tests/key_aliases/regular_key", + "meta": { + "name": "behavior_tests/key_aliases/regular_key", + "tags": [], + "description": "", + "archived": false + }, + "implementation": { + "type": "const", + "value": "hello" + }, + "valueType": "string", + "dependencies": [] +} diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/banana.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/banana.json index be892ee1a..02e21697a 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/banana.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/banana.json @@ -12,6 +12,5 @@ "value": "value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/green_apple.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/green_apple.json index 75b5177b0..7b901d6f4 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/green_apple.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/green_apple.json @@ -12,6 +12,5 @@ "value": "value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/red_apple.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/red_apple.json index 037e80c69..57597fc96 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/red_apple.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/keys_list/red_apple.json @@ -12,6 +12,5 @@ "value": "value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition.json index b4f7d6ead..085e7c40e 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition_group.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition_group.json index c756a1440..427c45785 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition_group.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/add_partition_group.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/delete_partition.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/delete_partition.json index 8da930da5..ca725593f 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/delete_partition.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/delete_partition.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/empty_partition.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/empty_partition.json index 6d8893a7f..d963e2e85 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/empty_partition.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/empty_partition.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/partition_groups.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/partition_groups.json index 3c15c997d..319ec842b 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/partition_groups.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/partitions/partition_groups.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/read_only.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/read_only.json index c3243fd37..f9d042c92 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/read_only.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/read_only.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/revision_history.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/revision_history.json index 82b75b8c6..e8794cf21 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/revision_history.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/revision_history.json @@ -12,6 +12,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/routing.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/routing.json index 765577bc6..a323917f7 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/routing.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/routing.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/tags.json b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/tags.json index cfd4ae1da..24044721e 100644 --- a/services/git-service/BareRepository/tests-source/manifests/behavior_tests/tags.json +++ b/services/git-service/BareRepository/tests-source/manifests/behavior_tests/tags.json @@ -11,6 +11,5 @@ "value": "value" }, "valueType": "string", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/integration_tests/alias_key.json b/services/git-service/BareRepository/tests-source/manifests/integration_tests/alias_key.json new file mode 100644 index 000000000..7fb343d14 --- /dev/null +++ b/services/git-service/BareRepository/tests-source/manifests/integration_tests/alias_key.json @@ -0,0 +1,10 @@ +{ + "key_path": "integration_tests/alias_key", + "meta": { + "archived": false + }, + "implementation": { + "type": "alias", + "key": "integration_tests/some_key" + } +} \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@integration_tests/some_key.json b/services/git-service/BareRepository/tests-source/manifests/integration_tests/some_key.json similarity index 57% rename from services/git-service/BareRepository/tests-source/manifests/@integration_tests/some_key.json rename to services/git-service/BareRepository/tests-source/manifests/integration_tests/some_key.json index 6cc8f5cea..f2d9769c2 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@integration_tests/some_key.json +++ b/services/git-service/BareRepository/tests-source/manifests/integration_tests/some_key.json @@ -1,7 +1,7 @@ { - "key_path": "@integration_tests/some_key", + "key_path": "integration_tests/some_key", "meta": { - "name": "@integration_tests/some_key", + "name": "integration_tests/some_key", "tags": [], "description": "", "archived": false @@ -11,6 +11,5 @@ "value": 1 }, "valueType": "number", - "dependencies": [], - "enabled": true + "dependencies": [] } diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/identity_context/color.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/identity_context/color.json similarity index 75% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/identity_context/color.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/identity_context/color.json index d91c4a6d8..e8a29cb22 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/identity_context/color.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/identity_context/color.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/identity_context/color", + "key_path": "smoke_tests/identity_context/color", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path/key1.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path/key1.json similarity index 77% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path/key1.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path/key1.json index b4469fcab..b28d5ce4c 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path/key1.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path/key1.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/key_path/key1", + "key_path": "smoke_tests/key_path/key1", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "test" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path/key2.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path/key2.json similarity index 77% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path/key2.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path/key2.json index 25cc85bd8..48d3a46a6 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path/key2.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path/key2.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/key_path/key2", + "key_path": "smoke_tests/key_path/key2", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "test" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path_.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path_.json similarity index 78% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path_.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path_.json index 83d370050..637c8b33c 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path_.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path_.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/key_path_", + "key_path": "smoke_tests/key_path_", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "some value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path_suffix/key.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path_suffix/key.json similarity index 76% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path_suffix/key.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path_suffix/key.json index 66fa08983..9b2fadc6a 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/key_path_suffix/key.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/key_path_suffix/key.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/key_path_suffix/key", + "key_path": "smoke_tests/key_path_suffix/key", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "some value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@hidden/@hidden_key.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@hidden/@hidden_key.json similarity index 73% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@hidden/@hidden_key.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@hidden/@hidden_key.json index d4beeb0b8..31d4d639a 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@hidden/@hidden_key.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@hidden/@hidden_key.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/not_hidden/@hidden/@hidden_key", + "key_path": "smoke_tests/not_hidden/@hidden/@hidden_key", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "hidden value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@hidden/visible_key.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@hidden/visible_key.json similarity index 74% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@hidden/visible_key.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@hidden/visible_key.json index 1077a4816..696c615b4 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@hidden/visible_key.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@hidden/visible_key.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/not_hidden/@hidden/visible_key", + "key_path": "smoke_tests/not_hidden/@hidden/visible_key", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "visible value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@some_hidden_key.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@some_hidden_key.json similarity index 75% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@some_hidden_key.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@some_hidden_key.json index bec22d100..8dd1e0c7d 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/@some_hidden_key.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/@some_hidden_key.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/not_hidden/@some_hidden_key", + "key_path": "smoke_tests/not_hidden/@some_hidden_key", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "some hidden value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/some_key.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/some_key.json similarity index 76% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/some_key.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/some_key.json index 2e9febf76..7e4e85368 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/not_hidden/some_key.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/not_hidden/some_key.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/not_hidden/some_key", + "key_path": "smoke_tests/not_hidden/some_key", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "value": "some value" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/comparison.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/comparison.json similarity index 74% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/comparison.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/comparison.json index 21ed01d57..ac9d88dab 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/comparison.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/comparison.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/rule_based_keys/comparison", + "key_path": "smoke_tests/rule_based_keys/comparison", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/in.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/in.json similarity index 76% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/in.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/in.json index 2e1b6a1d0..d8d1d6e77 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/in.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/in.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/rule_based_keys/in", + "key_path": "smoke_tests/rule_based_keys/in", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/multi_conditions.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/multi_conditions.json similarity index 72% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/multi_conditions.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/multi_conditions.json index 86866369d..6d4428725 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/multi_conditions.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/multi_conditions.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/rule_based_keys/multi_conditions", + "key_path": "smoke_tests/rule_based_keys/multi_conditions", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/simple.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/simple.json similarity index 75% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/simple.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/simple.json index 2f300302e..5c958d0b8 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/rule_based_keys/simple.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/rule_based_keys/simple.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/rule_based_keys/simple", + "key_path": "smoke_tests/rule_based_keys/simple", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/value_distribution/bernoulli.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/value_distribution/bernoulli.json similarity index 73% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/value_distribution/bernoulli.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/value_distribution/bernoulli.json index be8567722..723d93c13 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/value_distribution/bernoulli.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/value_distribution/bernoulli.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/value_distribution/bernoulli", + "key_path": "smoke_tests/value_distribution/bernoulli", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/value_distribution/weighted_normalized.json b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/value_distribution/weighted_normalized.json similarity index 71% rename from services/git-service/BareRepository/tests-source/manifests/@smoke_tests/value_distribution/weighted_normalized.json rename to services/git-service/BareRepository/tests-source/manifests/smoke_tests/value_distribution/weighted_normalized.json index a81054dd1..bab554ac9 100644 --- a/services/git-service/BareRepository/tests-source/manifests/@smoke_tests/value_distribution/weighted_normalized.json +++ b/services/git-service/BareRepository/tests-source/manifests/smoke_tests/value_distribution/weighted_normalized.json @@ -1,5 +1,5 @@ { - "key_path": "@smoke_tests/value_distribution/weighted_normalized", + "key_path": "smoke_tests/value_distribution/weighted_normalized", "meta": { "description": "", "readOnly": false, @@ -10,6 +10,5 @@ "format": "jpad" }, "valueType": "string", - "enabled": true, "dependencies": [] } \ No newline at end of file diff --git a/services/management/package.json b/services/management/package.json index a4ca4011f..8e37bc9d9 100644 --- a/services/management/package.json +++ b/services/management/package.json @@ -1,6 +1,6 @@ { "name": "tweek-management", - "version": "0.2.2", + "version": "0.3.0", "main": "src/server.js", "repository": "Soluto/tweek", "author": "Soluto", diff --git a/services/management/src/build-rules-artifiact.js b/services/management/src/build-rules-artifiact.js index d52270345..d171dff37 100644 --- a/services/management/src/build-rules-artifiact.js +++ b/services/management/src/build-rules-artifiact.js @@ -3,40 +3,37 @@ const { Observable } = require('rxjs'); const indexByName = R.indexBy(R.prop('name')); -module.exports = function(files) { - //todo remove legacy support - files = files.map(file => - Object.assign({}, file, { - name: file.name.replace(/^meta\//, 'manifests/').replace(/^rules\//, 'implementations/jpad/'), - }), - ); - - const metaFiles = files.filter(x => x.name.startsWith('manifests/')); +module.exports = function (files) { + const manifestFiles = files.filter(x => x.name.startsWith('manifests/')); const index = indexByName(files); - return Observable.from(metaFiles) + return Observable.from(manifestFiles) .flatMap(file => Observable.defer(file.read)) - .map(JSON.parse) - .map(meta => + .map(x => JSON.parse(x)) + .map(manifest => Observable.defer(async () => { const keyDef = { - dependencies: meta.dependencies, + dependencies: manifest.dependencies, + format: manifest.implementation.format || manifest.implementation.type, }; - switch (meta.implementation.type) { - case 'file': { - const { format, extension } = meta.implementation; - keyDef.format = format; - keyDef.payload = await index[ - `implementations/${format}/${meta.key_path}.${extension || format}` - ].read(); - break; - } - case 'const': { - keyDef.format = 'const'; - keyDef.payload = JSON.stringify(meta.implementation.value); - break; - } + switch (manifest.implementation.type) { + case 'file': { + const { format, extension } = manifest.implementation; + keyDef.payload = await index[ + `implementations/${format}/${manifest.key_path}.${extension || format}` + ].read(); + break; + } + case 'const': { + keyDef.payload = JSON.stringify(manifest.implementation.value); + break; + } + case 'alias': { + keyDef.payload = manifest.implementation.key; + keyDef.dependencies = [manifest.implementation.key]; + break; + } } - return [meta.key_path, keyDef]; + return [manifest.key_path, keyDef]; }), ) .mergeAll(10) diff --git a/services/management/test/build-rules-artifact-spec.js b/services/management/test/build-rules-artifact-spec.js index 5228fc632..8a53a4d17 100644 --- a/services/management/test/build-rules-artifact-spec.js +++ b/services/management/test/build-rules-artifact-spec.js @@ -34,6 +34,14 @@ describe('build rules artifact', () => { value: 'some-value', }, }, + 'manifests/alias': { + key_path: 'alias', + dependencies: ['wrong_dep'], + implementation: { + type: 'alias', + key: 'some_key', + }, + }, }; const files = getFiles(filesToRead); const expectedArtifact = { @@ -47,6 +55,11 @@ describe('build rules artifact', () => { payload: JSON.stringify('some-value'), dependencies: [], }, + alias: { + format: 'alias', + payload: 'some_key', + dependencies: ['some_key'], + }, }; const artifacts = buildRulesArtifact(files);