diff --git a/tests/Fixture/AuthKeysFixture.php b/tests/Fixture/AuthKeysFixture.php new file mode 100644 index 0000000..24034f3 --- /dev/null +++ b/tests/Fixture/AuthKeysFixture.php @@ -0,0 +1,85 @@ +records = [ + [ + 'id' => self::ADMIN_API_ID, + 'uuid' => $faker->uuid(), + 'authkey' => $hasher->hash(self::ADMIN_API_KEY), + 'authkey_start' => substr(self::ADMIN_API_KEY, 0, 4), + 'authkey_end' => substr(self::ADMIN_API_KEY, -4), + 'expiration' => 0, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'comment' => '', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::SYNC_API_ID, + 'uuid' => $faker->uuid(), + 'authkey' => $hasher->hash(self::SYNC_API_KEY), + 'authkey_start' => substr(self::SYNC_API_KEY, 0, 4), + 'authkey_end' => substr(self::SYNC_API_KEY, -4), + 'expiration' => 0, + 'user_id' => UsersFixture::USER_SYNC_ID, + 'comment' => '', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::ORG_ADMIN_API_ID, + 'uuid' => $faker->uuid(), + 'authkey' => $hasher->hash(self::ORG_ADMIN_API_KEY), + 'authkey_start' => substr(self::ORG_ADMIN_API_KEY, 0, 4), + 'authkey_end' => substr(self::ORG_ADMIN_API_KEY, -4), + 'expiration' => 0, + 'user_id' => UsersFixture::USER_ORG_ADMIN_ID, + 'comment' => '', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::REGULAR_USER_API_ID, + 'uuid' => $faker->uuid(), + 'authkey' => $hasher->hash(self::REGULAR_USER_API_KEY), + 'authkey_start' => substr(self::REGULAR_USER_API_KEY, 0, 4), + 'authkey_end' => substr(self::REGULAR_USER_API_KEY, -4), + 'expiration' => 0, + 'user_id' => UsersFixture::USER_REGULAR_USER_ID, + 'comment' => '', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ] + ]; + parent::init(); + } +} diff --git a/tests/Fixture/BroodsFixture.php b/tests/Fixture/BroodsFixture.php new file mode 100644 index 0000000..c329e6a --- /dev/null +++ b/tests/Fixture/BroodsFixture.php @@ -0,0 +1,72 @@ +records = [ + [ + 'id' => self::BROOD_A_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Brood A', + 'url' => $faker->url, + 'description' => $faker->text, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'trusted' => true, + 'pull' => true, + 'skip_proxy' => true, + 'authkey' => self::BROOD_A_API_KEY, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::BROOD_B_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Brood A', + 'url' => $faker->url, + 'description' => $faker->text, + 'organisation_id' => OrganisationsFixture::ORGANISATION_B_ID, + 'trusted' => true, + 'pull' => true, + 'skip_proxy' => true, + 'authkey' => self::BROOD_B_API_KEY, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::BROOD_WIREMOCK_ID, + 'uuid' => $faker->uuid(), + 'name' => 'wiremock', + 'url' => 'http://localhost:8080', + 'description' => $faker->text, + 'organisation_id' => OrganisationsFixture::ORGANISATION_B_ID, + 'trusted' => true, + 'pull' => true, + 'skip_proxy' => true, + 'authkey' => self::BROOD_WIREMOCK_API_KEY, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ] + ]; + parent::init(); + } +} diff --git a/tests/Fixture/EncryptionKeysFixture.php b/tests/Fixture/EncryptionKeysFixture.php new file mode 100644 index 0000000..a9d6c27 --- /dev/null +++ b/tests/Fixture/EncryptionKeysFixture.php @@ -0,0 +1,133 @@ +records = [ + [ + 'id' => self::ENCRYPTION_KEY_ORG_A_ID, + 'uuid' => $faker->uuid(), + 'type' => self::TYPE_PGP, + 'encryption_key' => $this->getPublicKey(self::KEY_TYPE_EDCH), + 'revoked' => false, + 'expires' => null, + 'owner_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'owner_model' => 'Organisation', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::ENCRYPTION_KEY_ORG_B_ID, + 'uuid' => $faker->uuid(), + 'type' => self::TYPE_PGP, + 'encryption_key' => $this->getPublicKey(self::KEY_TYPE_EDCH), + 'revoked' => false, + 'expires' => null, + 'owner_id' => OrganisationsFixture::ORGANISATION_B_ID, + 'owner_model' => 'Organisation', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + ]; + parent::init(); + } + + public static function getPublicKey(string $type): string + { + switch ($type) { + case self::KEY_TYPE_EDCH: + return <<records = [ + [ + 'id' => self::INBOX_USER_REGISTRATION_ID, + 'uuid' => $faker->uuid(), + 'scope' => 'User', + 'action' => 'Registration', + 'title' => 'User account creation requested for foo@bar.com', + 'origin' => '::1', + 'comment' => null, + 'description' => 'Handle user account for this cerebrate instance', + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'data' => [ + 'email' => 'foo@bar.com', + 'password' => '$2y$10$dr5C0MWgBx1723yyws0HPudTqHz4k8wJ1PQ1ApVkNuH64LuZAr\/ve', + ], + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::INBOX_INCOMING_CONNECTION_REQUEST_ID, + 'uuid' => $faker->uuid(), + 'scope' => 'LocalTool', + 'action' => 'IncomingConnectionRequest', + 'title' => 'Request for MISP Inter-connection', + 'origin' => 'http://127.0.0.1', + 'comment' => null, + 'description' => 'Handle Phase I of inter-connection when another cerebrate instance performs the request.', + 'user_id' => UsersFixture::USER_ORG_ADMIN_ID, + 'data' => [ + 'connectorName' => 'MispConnector', + 'cerebrateURL' => 'http://127.0.0.1', + 'local_tool_id' => 1, + 'remote_tool_id' => 1, + ], + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + ]; + parent::init(); + } +} diff --git a/tests/Fixture/IndividualsFixture.php b/tests/Fixture/IndividualsFixture.php new file mode 100644 index 0000000..13aecdf --- /dev/null +++ b/tests/Fixture/IndividualsFixture.php @@ -0,0 +1,77 @@ +records = [ + [ + 'id' => self::INDIVIDUAL_ADMIN_ID, + 'uuid' => $faker->uuid(), + 'email' => $faker->email(), + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'position' => 'admin', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::INDIVIDUAL_SYNC_ID, + 'uuid' => $faker->uuid(), + 'email' => $faker->email(), + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'position' => 'sync', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::INDIVIDUAL_ORG_ADMIN_ID, + 'uuid' => $faker->uuid(), + 'email' => $faker->email(), + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'position' => 'org_admin', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::INDIVIDUAL_REGULAR_USER_ID, + 'uuid' => $faker->uuid(), + 'email' => $faker->email(), + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'position' => 'user', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::INDIVIDUAL_A_ID, + 'uuid' => $faker->uuid(), + 'email' => $faker->email(), + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'position' => 'user', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ] + ]; + parent::init(); + } +} diff --git a/tests/Fixture/OrganisationsFixture.php b/tests/Fixture/OrganisationsFixture.php new file mode 100644 index 0000000..8531d0c --- /dev/null +++ b/tests/Fixture/OrganisationsFixture.php @@ -0,0 +1,48 @@ +records = [ + [ + 'id' => self::ORGANISATION_A_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Organisation A', + 'url' => $faker->url, + 'nationality' => $faker->countryCode, + 'sector' => 'IT', + 'type' => '', + 'contacts' => '', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::ORGANISATION_B_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Organisation B', + 'url' => $faker->url, + 'nationality' => $faker->countryCode, + 'sector' => 'IT', + 'type' => '', + 'contacts' => '', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ] + ]; + parent::init(); + } +} diff --git a/tests/Fixture/RolesFixture.php b/tests/Fixture/RolesFixture.php new file mode 100644 index 0000000..1230e8f --- /dev/null +++ b/tests/Fixture/RolesFixture.php @@ -0,0 +1,62 @@ +records = [ + [ + 'id' => self::ROLE_ADMIN_ID, + 'uuid' => $faker->uuid(), + 'name' => 'admin', + 'is_default' => false, + 'perm_admin' => true, + 'perm_sync' => false, + 'perm_org_admin' => false + ], + [ + 'id' => self::ROLE_SYNC_ID, + 'uuid' => $faker->uuid(), + 'name' => 'sync', + 'is_default' => false, + 'perm_admin' => false, + 'perm_sync' => true, + 'perm_org_admin' => false + ], + [ + 'id' => self::ROLE_ORG_ADMIN_ID, + 'uuid' => $faker->uuid(), + 'name' => 'org_admin', + 'is_default' => false, + 'perm_admin' => false, + 'perm_sync' => false, + 'perm_org_admin' => true + ], + [ + 'id' => self::ROLE_REGULAR_USER_ID, + 'uuid' => $faker->uuid(), + 'name' => 'user', + 'is_default' => true, + 'perm_admin' => false, + 'perm_sync' => false, + 'perm_org_admin' => false + ] + ]; + parent::init(); + } +} diff --git a/tests/Fixture/SharingGroupsFixture.php b/tests/Fixture/SharingGroupsFixture.php new file mode 100644 index 0000000..79665b6 --- /dev/null +++ b/tests/Fixture/SharingGroupsFixture.php @@ -0,0 +1,50 @@ +records = [ + [ + 'id' => self::SHARING_GROUP_A_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Sharing Group A', + 'releasability' => 'Sharing Group A releasability', + 'description' => 'Sharing Group A description', + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'active' => true, + 'local' => true, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::SHARING_GROUP_B_ID, + 'uuid' => $faker->uuid(), + 'name' => 'Sharing Group B', + 'releasability' => 'Sharing Group B releasability', + 'description' => 'Sharing Group B description', + 'organisation_id' => OrganisationsFixture::ORGANISATION_B_ID, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'active' => true, + 'local' => true, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + ]; + parent::init(); + } +} diff --git a/tests/Fixture/TagsTaggedsFixture.php b/tests/Fixture/TagsTaggedsFixture.php new file mode 100644 index 0000000..e2bf70f --- /dev/null +++ b/tests/Fixture/TagsTaggedsFixture.php @@ -0,0 +1,40 @@ +records = [ + [ + 'tag_id' => TagsTagsFixture::TAG_ORG_A_ID, + 'fk_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'fk_model' => 'Organisations', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'tag_id' => TagsTagsFixture::TAG_ORG_B_ID, + 'fk_id' => OrganisationsFixture::ORGANISATION_B_ID, + 'fk_model' => 'Organisations', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + ]; + parent::init(); + } +} diff --git a/tests/Fixture/TagsTagsFixture.php b/tests/Fixture/TagsTagsFixture.php new file mode 100644 index 0000000..002bc9e --- /dev/null +++ b/tests/Fixture/TagsTagsFixture.php @@ -0,0 +1,87 @@ +records = [ + [ + 'id' => self::TAG_RED_ID, + 'name' => 'red', + 'namespace' => null, + 'predicate' => null, + 'value' => null, + 'colour' => 'FF0000', + 'counter' => 0, + 'text_colour' => 'red', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::TAG_GREEN_ID, + 'name' => 'green', + 'namespace' => null, + 'predicate' => null, + 'value' => null, + 'colour' => '00FF00', + 'counter' => 0, + 'text_colour' => 'green', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::TAG_BLUE_ID, + 'name' => 'blue', + 'namespace' => null, + 'predicate' => null, + 'value' => null, + 'colour' => '0000FF', + 'counter' => 0, + 'text_colour' => 'blue', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::TAG_ORG_A_ID, + 'name' => 'org-a', + 'namespace' => null, + 'predicate' => null, + 'value' => null, + 'colour' => '000000', + 'counter' => 0, + 'text_colour' => 'black', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::TAG_ORG_B_ID, + 'name' => 'org-b', + 'namespace' => null, + 'predicate' => null, + 'value' => null, + 'colour' => '000000', + 'counter' => 0, + 'text_colour' => 'black', + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ] + ]; + parent::init(); + } +} diff --git a/tests/Fixture/UsersFixture.php b/tests/Fixture/UsersFixture.php new file mode 100644 index 0000000..ba35e7a --- /dev/null +++ b/tests/Fixture/UsersFixture.php @@ -0,0 +1,92 @@ +records = [ + [ + 'id' => self::USER_ADMIN_ID, + 'uuid' => $faker->uuid(), + 'username' => self::USER_ADMIN_USERNAME, + 'password' => $hasher->hash(self::USER_ADMIN_PASSWORD), + 'role_id' => RolesFixture::ROLE_ADMIN_ID, + 'individual_id' => IndividualsFixture::INDIVIDUAL_ADMIN_ID, + 'disabled' => 0, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::USER_SYNC_ID, + 'uuid' => $faker->uuid(), + 'username' => self::USER_SYNC_USERNAME, + 'password' => $hasher->hash(self::USER_SYNC_PASSWORD), + 'role_id' => RolesFixture::ROLE_SYNC_ID, + 'individual_id' => IndividualsFixture::INDIVIDUAL_SYNC_ID, + 'disabled' => 0, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::USER_ORG_ADMIN_ID, + 'uuid' => $faker->uuid(), + 'username' => self::USER_ORG_ADMIN_USERNAME, + 'password' => $hasher->hash(self::USER_ORG_ADMIN_PASSWORD), + 'role_id' => RolesFixture::ROLE_ORG_ADMIN_ID, + 'individual_id' => IndividualsFixture::INDIVIDUAL_ORG_ADMIN_ID, + 'disabled' => 0, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ], + [ + 'id' => self::USER_REGULAR_USER_ID, + 'uuid' => $faker->uuid(), + 'username' => self::USER_REGULAR_USER_USERNAME, + 'password' => $hasher->hash(self::USER_REGULAR_USER_PASSWORD), + 'role_id' => RolesFixture::ROLE_REGULAR_USER_ID, + 'individual_id' => IndividualsFixture::INDIVIDUAL_REGULAR_USER_ID, + 'disabled' => 0, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'created' => $faker->dateTime()->getTimestamp(), + 'modified' => $faker->dateTime()->getTimestamp() + ] + ]; + parent::init(); + } +} diff --git a/tests/Helper/ApiTestTrait.php b/tests/Helper/ApiTestTrait.php new file mode 100644 index 0000000..a55268c --- /dev/null +++ b/tests/Helper/ApiTestTrait.php @@ -0,0 +1,294 @@ +initializeOpenApiValidator(); + } + + public function setAuthToken(string $authToken): void + { + $this->_authToken = $authToken; + + // somehow this is not set automatically in test environment + $_SERVER['HTTP_AUTHORIZATION'] = $authToken; + + $this->configRequest([ + 'headers' => [ + 'Accept' => 'application/json', + 'Authorization' => $this->_authToken, + 'Content-Type' => 'application/json' + ] + ]); + } + + /** + * Skip OpenAPI validations. + * + * @return void + */ + public function skipOpenApiValidations(): void + { + $this->_skipOpenApiValidations = true; + } + + public function assertResponseContainsArray(array $expected): void + { + $responseArray = json_decode((string)$this->_response->getBody(), true); + throw new NotImplementedException('TODO: see codeception seeResponseContainsJson()'); + } + + /** + * Load OpenAPI specification validator + * + * @return void + */ + public function initializeOpenApiValidator(): void + { + if (!$this->_skipOpenApiValidations) { + $this->_validator = Configure::read('App.OpenAPIValidator'); + if ($this->_validator === null) { + throw new \Exception('OpenAPI validator is not configured'); + } + } + } + + /** + * Validates the API request against the OpenAPI spec + * + * @return void + */ + public function assertRequestMatchesOpenApiSpec(): void + { + $this->_validator->getRequestValidator()->validate($this->_psrRequest); + } + + /** + * Validates the API response against the OpenAPI spec + * + * @param string $path The path to the API endpoint + * @param string $method The HTTP method used to call the endpoint + * @return void + */ + public function assertResponseMatchesOpenApiSpec(string $endpoint, string $method = 'get'): void + { + $address = new OperationAddress($endpoint, $method); + $this->_validator->getResponseValidator()->validate($address, $this->_response); + } + + /** + * Validates a record exists in the database + * + * @param string $table The table name + * @param array $conditions The conditions to check + * @return void + * @throws \Exception + * @throws \Cake\Datasource\Exception\RecordNotFoundException + * + * @see https://book.cakephp.org/4/en/orm-query-builder.html + */ + public function assertDbRecordExists(string $table, array $conditions): void + { + $record = $this->getTableLocator()->get($table)->find()->where($conditions)->first(); + if (!$record) { + throw new \PHPUnit\Framework\AssertionFailedError("Record not found in table '$table' with conditions: " . json_encode($conditions)); + } + $this->assertNotEmpty($record); + } + + /** + * Validates a record do not exists in the database + * + * @param string $table The table name + * @param array $conditions The conditions to check + * @return void + * @throws \Exception + * @throws \Cake\Datasource\Exception\RecordNotFoundException + * + * @see https://book.cakephp.org/4/en/orm-query-builder.html + */ + public function assertDbRecordNotExists(string $table, array $conditions): void + { + $record = $this->getTableLocator()->get($table)->find()->where($conditions)->first(); + if ($record) { + throw new \PHPUnit\Framework\AssertionFailedError("Record found in table '$table' with conditions: " . json_encode($conditions)); + } + $this->assertEmpty($record); + } + + /** + * Parses the response body and returns the decoded JSON + * + * @return array + * @throws \Exception + */ + public function getJsonResponseAsArray(): array + { + if ($this->_response->getHeaders()['Content-Type'][0] !== 'application/json') { + throw new \Exception('The response is not a JSON response'); + } + + return json_decode((string)$this->_response->getBody(), true); + } + + /** + * Gets a database records as an array + * + * @param string $table The table name + * @param array $conditions The conditions to check + * @return array + * @throws \Cake\Datasource\Exception\RecordNotFoundException + */ + public function getRecordFromDb(string $table, array $conditions): array + { + return $this->getTableLocator()->get($table)->find()->where($conditions)->first()->toArray(); + } + + /** + * This method intercepts IntegrationTestTrait::_buildRequest() + * in the quest to get a PSR-7 request object and saves it for + * later inspection, also validates it against the OpenAPI spec. + * @see \Cake\TestSuite\IntegrationTestTrait::_buildRequest() + * + * @param string $url The URL + * @param string $method The HTTP method + * @param array|string $data The request data. + * @return array The request context + */ + protected function _buildRequest(string $url, $method, $data = []): array + { + $spec = $this->_buildRequestOriginal($url, $method, $data); + + $this->_psrRequest = $this->_createPsr7RequestFromSpec($spec); + + // Validate request against OpenAPI spec + if (!$this->_skipOpenApiValidations) { + try { + $this->assertRequestMatchesOpenApiSpec(); + } catch (\Exception $exception) { + $this->fail($exception->getMessage()); + } + } else { + $this->addWarning( + sprintf( + 'OpenAPI spec validations skipped for request [%s]%s.', + $this->_psrRequest->getMethod(), + $this->_psrRequest->getPath() + ) + ); + } + + return $spec; + } + + /** + * This method intercepts IntegrationTestTrait::_buildRequest() + * and validates the response against the OpenAPI spec. + * + * @see \Cake\TestSuite\IntegrationTestTrait::_sendRequest() + * + * @param array|string $url The URL + * @param string $method The HTTP method + * @param array|string $data The request data. + * @return void + * @throws \PHPUnit\Exception|\Throwable + */ + protected function _sendRequest($url, $method, $data = []): void + { + // Adding Content-Type: application/json $this->configRequest() prevents this from happening somehow + if (in_array($method, ['POST', 'PATCH', 'PUT']) && $this->_request['headers']['Content-Type'] === 'application/json') { + $data = json_encode($data); + } + + $this->_sendRequestOriginal($url, $method, $data); + + // Validate response against OpenAPI spec + if (!$this->_skipOpenApiValidations) { + $this->assertResponseMatchesOpenApiSpec( + $this->_psrRequest->getPath(), + strtolower($this->_psrRequest->getMethod()) + ); + } else { + $this->addWarning( + sprintf( + 'OpenAPI spec validations skipped for response of [%s]%s.', + $this->_psrRequest->getMethod(), + $this->_psrRequest->getPath() + ) + ); + } + } + + /** + * Create a PSR-7 request from the request spec. + * @see \Cake\TestSuite\MiddlewareDispatcher::_createRequest() + * + * @param array $spec The request spec. + * @return \Cake\Http\ServerRequest + */ + private function _createPsr7RequestFromSpec(array $spec): ServerRequest + { + if (isset($spec['input'])) { + $spec['post'] = []; + $spec['environment']['CAKEPHP_INPUT'] = $spec['input']; + } + $environment = array_merge( + array_merge($_SERVER, ['REQUEST_URI' => $spec['url']]), + $spec['environment'] + ); + if (strpos($environment['PHP_SELF'], 'phpunit') !== false) { + $environment['PHP_SELF'] = '/'; + } + return ServerRequestFactory::fromGlobals( + $environment, + $spec['query'], + $spec['post'], + $spec['cookies'], + $spec['files'] + ); + } +} diff --git a/tests/Helper/WireMockTestTrait.php b/tests/Helper/WireMockTestTrait.php new file mode 100644 index 0000000..9b42f7e --- /dev/null +++ b/tests/Helper/WireMockTestTrait.php @@ -0,0 +1,49 @@ + */ + private $config = [ + 'hostname' => 'localhost', + 'port' => 8080 + ]; + + public function initializeWireMock(): void + { + $this->wiremock = WireMock::create( + $_ENV['WIREMOCK_HOST'] ?? $this->config['hostname'], + $_ENV['WIREMOCK_PORT'] ?? $this->config['port'] + ); + + if (!$this->wiremock->isAlive()) { + throw new Exception('Failed to connect to WireMock server.'); + } + + $this->clearWireMockStubs(); + } + + public function clearWireMockStubs(): void + { + $this->wiremock->resetToDefault(); + } + + public function getWireMock(): WireMock + { + return $this->wiremock; + } + + public function getWireMockBaseUrl(): string + { + return sprintf('http://%s:%s', $this->config['hostname'], $this->config['port']); + } +} diff --git a/tests/Helper/wiremock/start.sh b/tests/Helper/wiremock/start.sh new file mode 100644 index 0000000..60b8197 --- /dev/null +++ b/tests/Helper/wiremock/start.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Adapted from @rowanhill wiremock start.sh script +# https://github.com/rowanhill/wiremock-php/blob/master/wiremock/start.sh + +cd ./tmp/ + +instance=1 +port=8080 +if [ $# -gt 0 ]; then + instance=$1 + port=$2 +fi +pidFile=wiremock.$instance.pid +logFile=wiremock.$instance.log + +# Ensure WireMock isn't already running +if [ -e $pidFile ]; then + echo WireMock is already started: see process `cat $pidFile` 1>&2 + exit 0 +fi + +# Download the wiremock jar if we need it +if ! [ -e wiremock-standalone.jar ]; then + echo WireMock standalone JAR missing. Downloading. + curl https://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-jre8-standalone/2.32.0/wiremock-jre8-standalone-2.32.0.jar -o wiremock-standalone.jar + status=$? + if [ ${status} -ne 0 ]; then + echo curl could not download WireMock JAR 1>&2 + exit ${status} + fi +fi + +# Start WireMock in standalone mode (in a background process) and save its output to a log +java -jar wiremock-standalone.jar --port $port --root-dir $instance --disable-banner &> $logFile 2>&1 & +pgrep -f wiremock-standalone.jar > $pidFile + +echo WireMock $instance started on port $port \ No newline at end of file diff --git a/tests/Helper/wiremock/stop.sh b/tests/Helper/wiremock/stop.sh new file mode 100644 index 0000000..f9e3f9e --- /dev/null +++ b/tests/Helper/wiremock/stop.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Adapted from @rowanhill wiremock stop.sh script +# https://github.com/rowanhill/wiremock-php/blob/master/wiremock/stop.sh + +cd ./tmp/ + +instance=1 +if [ $# -gt 0 ]; then + instance=$1 +fi +pidFile=wiremock.$instance.pid + + +if [ -e $pidFile ]; then + kill -9 `cat $pidFile` + rm $pidFile +else + echo WireMock is not started 2>&1 + exit 1 +fi + +echo WireMock $instance stopped \ No newline at end of file diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..434f84a --- /dev/null +++ b/tests/README.md @@ -0,0 +1,123 @@ +# Testing +1. Add a `cerebrate_test` database to the database: +```mysql +CREATE DATABASE cerebrate_test; +GRANT ALL PRIVILEGES ON cerebrate_test.* to cerebrate@localhost; +FLUSH PRIVILEGES; +QUIT; +``` + +2. Add a the test database to your `config/app_local.php` config file and set `debug` mode to `true`. +```php +'debug' => true, +'Datasources' => [ + 'default' => [ + ... + ], + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'host' => 'localhost', + 'username' => 'cerebrate', + 'password' => 'cerebrate', + 'database' => 'cerebrate_test', + ], +], +``` + +## Runing the tests +``` +$ composer install +$ composer test +> sh ./tests/Helper/wiremock/start.sh +WireMock 1 started on port 8080 +> phpunit +[ * ] Running DB migrations, it may take some time ... + +The WireMock server is started ..... +port: 8080 +enable-browser-proxying: false +disable-banner: true +no-request-journal: false +verbose: false + +PHPUnit 8.5.22 by Sebastian Bergmann and contributors. + + +..... 5 / 5 (100%) + +Time: 11.61 seconds, Memory: 26.00 MB + +OK (5 tests, 15 assertions) +``` + +Running a specific suite: +``` +$ vendor/bin/phpunit --testsuite=api --testdox +``` +Available suites: +* `app`: runs all test suites +* `api`: runs only api tests +* `controller`: runs only controller tests +* _to be continued ..._ + +By default the database is re-generated before running the test suite, to skip this step and speed up the test run set the following env variable in `phpunit.xml`: +```xml + + ... + + +``` +## Extras +### WireMock +Some integration tests perform calls to external APIs, we use WireMock to mock the response of these API calls. + +To download and run WireMock run the following script in a separate terminal: + ``` + sh ./tests/Helper/wiremock/start.sh + ``` + +You can also run WireMock with docker, check the official docs: http://wiremock.org/docs/docker/ + +> NOTE: When running the tests with `composer test` WireMock is automatically started and stoped after the tests finish. + +The default `hostname` and `port` for WireMock are set in `phpunit.xml` as environment variables: +```xml + + ... + + + +``` +### Coverage +HTML: +``` +$ vendor/bin/phpunit --coverage-html tmp/coverage +``` + +XML: +``` +$ vendor/bin/phpunit --verbose --coverage-clover=coverage.xml +``` + +### OpenAPI validation +API tests can assert the API response matches the OpenAPI specification, after the request add this line: + +```php +$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT); +``` + +The default OpenAPI spec path is set in `phpunit.xml` as a environment variablea: +```xml + + ... + + +``` + +### Debugging tests +``` +$ export XDEBUG_CONFIG="idekey=IDEKEY" +$ phpunit +``` diff --git a/tests/TestCase/Api/AuthKeys/AddAuthKeyApiTest.php b/tests/TestCase/Api/AuthKeys/AddAuthKeyApiTest.php new file mode 100644 index 0000000..ca305e8 --- /dev/null +++ b/tests/TestCase/Api/AuthKeys/AddAuthKeyApiTest.php @@ -0,0 +1,72 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'authkey' => $faker->sha1, + 'expiration' => 0, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'comment' => $faker->text + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"uuid": "%s"', $uuid)); + $this->assertDbRecordExists('AuthKeys', ['uuid' => $uuid]); + } + + public function testAddAdminAuthKeyNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'authkey' => $faker->sha1, + 'expiration' => 0, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'comment' => $faker->text + ] + ); + + $this->assertResponseCode(404); + $this->addWarning('Should return 405 Method Not Allowed instead of 404 Not Found'); + $this->assertDbRecordNotExists('AuthKeys', ['uuid' => $uuid]); + } +} diff --git a/tests/TestCase/Api/AuthKeys/DeleteAuthKeyApiTest.php b/tests/TestCase/Api/AuthKeys/DeleteAuthKeyApiTest.php new file mode 100644 index 0000000..a621f37 --- /dev/null +++ b/tests/TestCase/Api/AuthKeys/DeleteAuthKeyApiTest.php @@ -0,0 +1,45 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, AuthKeysFixture::ADMIN_API_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('AuthKeys', ['id' => AuthKeysFixture::ADMIN_API_ID]); + } + + public function testDeleteOrgAdminAuthKeyNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, AuthKeysFixture::ORG_ADMIN_API_ID); + + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('AuthKeys', ['id' => AuthKeysFixture::ORG_ADMIN_API_ID]); + } +} diff --git a/tests/TestCase/Api/AuthKeys/IndexAuthKeysApiTest.php b/tests/TestCase/Api/AuthKeys/IndexAuthKeysApiTest.php new file mode 100644 index 0000000..0712480 --- /dev/null +++ b/tests/TestCase/Api/AuthKeys/IndexAuthKeysApiTest.php @@ -0,0 +1,42 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', AuthKeysFixture::ADMIN_API_ID)); + } + + public function testIndexDoesNotShowAdminAuthKeysAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseNotContains(sprintf('"id": %d', AuthKeysFixture::REGULAR_USER_API_KEY)); + } +} diff --git a/tests/TestCase/Api/Broods/AddBroodApiTest.php b/tests/TestCase/Api/Broods/AddBroodApiTest.php new file mode 100644 index 0000000..f064f61 --- /dev/null +++ b/tests/TestCase/Api/Broods/AddBroodApiTest.php @@ -0,0 +1,79 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'name' => 'Brood A', + 'url' => $faker->url, + 'description' => $faker->text, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'trusted' => true, + 'pull' => true, + 'skip_proxy' => true, + 'authkey' => $faker->sha1, + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"uuid": "%s"', $uuid)); + $this->assertDbRecordExists('Broods', ['uuid' => $uuid]); + } + + public function testAddBroodNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'name' => 'Brood A', + 'url' => $faker->url, + 'description' => $faker->text, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'trusted' => true, + 'pull' => true, + 'skip_proxy' => true, + 'authkey' => $faker->sha1, + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('Broods', ['uuid' => $uuid]); + } +} diff --git a/tests/TestCase/Api/Broods/DeleteBroodApiTest.php b/tests/TestCase/Api/Broods/DeleteBroodApiTest.php new file mode 100644 index 0000000..420bf01 --- /dev/null +++ b/tests/TestCase/Api/Broods/DeleteBroodApiTest.php @@ -0,0 +1,46 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, BroodsFixture::BROOD_A_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('Broods', ['id' => BroodsFixture::BROOD_A_ID]); + } + + public function testDeleteBroodNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, BroodsFixture::BROOD_A_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('Broods', ['id' => BroodsFixture::BROOD_A_ID]); + } +} diff --git a/tests/TestCase/Api/Broods/EditBroodApiTest.php b/tests/TestCase/Api/Broods/EditBroodApiTest.php new file mode 100644 index 0000000..ad5d70b --- /dev/null +++ b/tests/TestCase/Api/Broods/EditBroodApiTest.php @@ -0,0 +1,71 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, BroodsFixture::BROOD_A_ID); + $this->put( + $url, + [ + 'name' => 'Test Brood 4321', + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists( + 'Broods', + [ + 'id' => BroodsFixture::BROOD_A_ID, + 'name' => 'Test Brood 4321', + ] + ); + } + + public function testEditBroodNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, BroodsFixture::BROOD_B_ID); + $this->put( + $url, + [ + 'name' => 'Test Brood 1234' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists( + 'Broods', + [ + 'id' => BroodsFixture::BROOD_B_ID, + 'name' => 'Test Brood 1234' + ] + ); + } +} diff --git a/tests/TestCase/Api/Broods/IndexBroodsApiTest.php b/tests/TestCase/Api/Broods/IndexBroodsApiTest.php new file mode 100644 index 0000000..d70bc53 --- /dev/null +++ b/tests/TestCase/Api/Broods/IndexBroodsApiTest.php @@ -0,0 +1,35 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', BroodsFixture::BROOD_A_ID)); + } +} diff --git a/tests/TestCase/Api/Broods/TestBroodConnectionApiTest.php b/tests/TestCase/Api/Broods/TestBroodConnectionApiTest.php new file mode 100644 index 0000000..ee1117f --- /dev/null +++ b/tests/TestCase/Api/Broods/TestBroodConnectionApiTest.php @@ -0,0 +1,68 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->initializeWireMock(); + $this->mockCerebrateStatusResponse(); + + $url = sprintf('%s/%d', self::ENDPOINT, BroodsFixture::BROOD_WIREMOCK_ID); + $this->get($url); + + $this->getWireMock()->verify( + WireMock::getRequestedFor(WireMock::urlEqualTo('/instance/status.json')) + ->withHeader('Content-Type', WireMock::equalTo('application/json')) + ->withHeader('Authorization', WireMock::equalTo(BroodsFixture::BROOD_WIREMOCK_API_KEY)) + ); + + $this->assertResponseOk(); + $this->assertResponseContains('"user": "wiremock"'); + } + + private function mockCerebrateStatusResponse(): \WireMock\Stubbing\StubMapping + { + return $this->getWireMock()->stubFor( + WireMock::get(WireMock::urlEqualTo('/instance/status.json')) + ->willReturn(WireMock::aResponse() + ->withHeader('Content-Type', 'application/json') + ->withBody((string)json_encode([ + "version" => "0.1", + "application" => "Cerebrate", + "user" => [ + "id" => 1, + "username" => "wiremock", + "role" => [ + "id" => 1 + ] + ] + ]))) + ); + } +} diff --git a/tests/TestCase/Api/Broods/ViewBroodApiTest.php b/tests/TestCase/Api/Broods/ViewBroodApiTest.php new file mode 100644 index 0000000..bd9e5a7 --- /dev/null +++ b/tests/TestCase/Api/Broods/ViewBroodApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, BroodsFixture::BROOD_A_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', BroodsFixture::BROOD_A_ID)); + } +} diff --git a/tests/TestCase/Api/EncryptionKeys/AddEncryptionKeyApiTest.php b/tests/TestCase/Api/EncryptionKeys/AddEncryptionKeyApiTest.php new file mode 100644 index 0000000..00cc377 --- /dev/null +++ b/tests/TestCase/Api/EncryptionKeys/AddEncryptionKeyApiTest.php @@ -0,0 +1,76 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'type' => EncryptionKeysFixture::TYPE_PGP, + 'encryption_key' => EncryptionKeysFixture::getPublicKey(EncryptionKeysFixture::KEY_TYPE_EDCH), + 'revoked' => false, + 'expires' => null, + 'owner_id' => UsersFixture::USER_ADMIN_ID, + 'owner_model' => 'User' + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"uuid": "%s"', $uuid)); + $this->assertDbRecordExists('EncryptionKeys', ['uuid' => $uuid]); + } + + public function testAddAdminUserEncryptionKeyNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'type' => EncryptionKeysFixture::TYPE_PGP, + 'encryption_key' => EncryptionKeysFixture::getPublicKey(EncryptionKeysFixture::KEY_TYPE_EDCH), + 'revoked' => false, + 'expires' => null, + 'owner_id' => UsersFixture::USER_ADMIN_ID, + 'owner_model' => 'User' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('EncryptionKeys', ['uuid' => $uuid]); + } +} diff --git a/tests/TestCase/Api/EncryptionKeys/DeleteEncryptionKeyApiTest.php b/tests/TestCase/Api/EncryptionKeys/DeleteEncryptionKeyApiTest.php new file mode 100644 index 0000000..6ae8143 --- /dev/null +++ b/tests/TestCase/Api/EncryptionKeys/DeleteEncryptionKeyApiTest.php @@ -0,0 +1,46 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('EncryptionKeys', ['id' => EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID]); + } + + public function testDeleteEncryptionKeyNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, EncryptionKeysFixture::ENCRYPTION_KEY_ORG_B_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('EncryptionKeys', ['id' => EncryptionKeysFixture::ENCRYPTION_KEY_ORG_B_ID]); + } +} diff --git a/tests/TestCase/Api/EncryptionKeys/EditEncryptionKeyApiTest.php b/tests/TestCase/Api/EncryptionKeys/EditEncryptionKeyApiTest.php new file mode 100644 index 0000000..2636fc1 --- /dev/null +++ b/tests/TestCase/Api/EncryptionKeys/EditEncryptionKeyApiTest.php @@ -0,0 +1,70 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID); + $this->put( + $url, + [ + 'revoked' => true, + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists( + 'EncryptionKeys', + [ + 'id' => EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID, + 'revoked' => true, + ] + ); + } + + public function testRevokeAdminEncryptionKeyNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, EncryptionKeysFixture::ENCRYPTION_KEY_ORG_B_ID); + $this->put( + $url, + [ + 'revoked' => true + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists( + 'EncryptionKeys', + [ + 'id' => EncryptionKeysFixture::ENCRYPTION_KEY_ORG_B_ID, + 'revoked' => true + ] + ); + } +} diff --git a/tests/TestCase/Api/EncryptionKeys/IndexEncryptionKeysApiTest.php b/tests/TestCase/Api/EncryptionKeys/IndexEncryptionKeysApiTest.php new file mode 100644 index 0000000..844336d --- /dev/null +++ b/tests/TestCase/Api/EncryptionKeys/IndexEncryptionKeysApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID)); + } +} diff --git a/tests/TestCase/Api/EncryptionKeys/ViewEncryptionKeyApiTest.php b/tests/TestCase/Api/EncryptionKeys/ViewEncryptionKeyApiTest.php new file mode 100644 index 0000000..de324fb --- /dev/null +++ b/tests/TestCase/Api/EncryptionKeys/ViewEncryptionKeyApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', EncryptionKeysFixture::ENCRYPTION_KEY_ORG_A_ID)); + } +} diff --git a/tests/TestCase/Api/Inbox/CreateInboxEntryApiTest.php b/tests/TestCase/Api/Inbox/CreateInboxEntryApiTest.php new file mode 100644 index 0000000..8434d62 --- /dev/null +++ b/tests/TestCase/Api/Inbox/CreateInboxEntryApiTest.php @@ -0,0 +1,70 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + // to avoid $this->request->clientIp() to return null + $_SERVER['REMOTE_ADDR'] = '::1'; + + $url = sprintf("%s/%s/%s", self::ENDPOINT, 'User', 'Registration'); + $this->post( + $url, + [ + 'email' => 'john@example.com', + 'password' => 'Password12345!' + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains('"email": "john@example.com"'); + $this->assertDbRecordExists( + 'Inbox', + [ + 'id' => 3, // hacky, but `data` is json string cannot verify the value because of the hashed password + 'scope' => 'User', + 'action' => 'Registration', + ] + ); + } + + public function testAddUserRegistrationInboxNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf("%s/%s/%s", self::ENDPOINT, 'User', 'Registration'); + $this->post( + $url, + [ + 'email' => 'john@example.com', + 'password' => 'Password12345!' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('Inbox', ['id' => 3]); + } +} diff --git a/tests/TestCase/Api/Inbox/IndexInboxApiTest.php b/tests/TestCase/Api/Inbox/IndexInboxApiTest.php new file mode 100644 index 0000000..ae9c039 --- /dev/null +++ b/tests/TestCase/Api/Inbox/IndexInboxApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', InboxFixture::INBOX_USER_REGISTRATION_ID)); + $this->assertResponseContains(sprintf('"id": %d', InboxFixture::INBOX_INCOMING_CONNECTION_REQUEST_ID)); + } +} diff --git a/tests/TestCase/Api/Individuals/AddIndividualApiTest.php b/tests/TestCase/Api/Individuals/AddIndividualApiTest.php new file mode 100644 index 0000000..fcff319 --- /dev/null +++ b/tests/TestCase/Api/Individuals/AddIndividualApiTest.php @@ -0,0 +1,59 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->post( + self::ENDPOINT, + [ + 'email' => 'john@example.com', + 'first_name' => 'John', + 'last_name' => 'Doe', + 'position' => 'Security Analyst' + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains('"email": "john@example.com"'); + $this->assertDbRecordExists('Individuals', ['email' => 'john@example.com']); + } + + // public function testAddUserNotAllowedAsRegularUser(): void + // { + // $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + // $this->post( + // self::ENDPOINT, + // [ + // 'email' => 'john@example.com', + // 'first_name' => 'John', + // 'last_name' => 'Doe', + // 'position' => 'Security Analyst' + // ] + // ); + + // $this->assertResponseCode(405); + // $this->assertDbRecordNotExists('Individuals', ['email' => 'john@example.com']); + // } +} diff --git a/tests/TestCase/Api/Individuals/DeleteIndividualApiTest.php b/tests/TestCase/Api/Individuals/DeleteIndividualApiTest.php new file mode 100644 index 0000000..e5657aa --- /dev/null +++ b/tests/TestCase/Api/Individuals/DeleteIndividualApiTest.php @@ -0,0 +1,45 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, IndividualsFixture::INDIVIDUAL_A_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('Individuals', ['id' => IndividualsFixture::INDIVIDUAL_A_ID]); + } + + public function testDeleteIndividualNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, IndividualsFixture::INDIVIDUAL_ADMIN_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('Individuals', ['id' => IndividualsFixture::INDIVIDUAL_ADMIN_ID]); + } +} diff --git a/tests/TestCase/Api/Individuals/EditIndividualApiTest.php b/tests/TestCase/Api/Individuals/EditIndividualApiTest.php new file mode 100644 index 0000000..c888bba --- /dev/null +++ b/tests/TestCase/Api/Individuals/EditIndividualApiTest.php @@ -0,0 +1,61 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, IndividualsFixture::INDIVIDUAL_REGULAR_USER_ID); + $this->put( + $url, + [ + 'email' => 'foo@bar.com', + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists('Individuals', [ + 'id' => IndividualsFixture::INDIVIDUAL_REGULAR_USER_ID, + 'email' => 'foo@bar.com' + ]); + } + + public function testEditAnyIndividualNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, IndividualsFixture::INDIVIDUAL_ADMIN_ID); + $this->put( + $url, + [ + 'email' => 'foo@bar.com', + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('Individuals', [ + 'id' => IndividualsFixture::INDIVIDUAL_ADMIN_ID, + 'email' => 'foo@bar.com' + ]); + } +} diff --git a/tests/TestCase/Api/Individuals/IndexIndividualsApiTest.php b/tests/TestCase/Api/Individuals/IndexIndividualsApiTest.php new file mode 100644 index 0000000..e5c92ce --- /dev/null +++ b/tests/TestCase/Api/Individuals/IndexIndividualsApiTest.php @@ -0,0 +1,34 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', IndividualsFixture::INDIVIDUAL_ADMIN_ID)); + } +} diff --git a/tests/TestCase/Api/Individuals/ViewIndividualApiTest.php b/tests/TestCase/Api/Individuals/ViewIndividualApiTest.php new file mode 100644 index 0000000..d4b94d9 --- /dev/null +++ b/tests/TestCase/Api/Individuals/ViewIndividualApiTest.php @@ -0,0 +1,35 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, IndividualsFixture::INDIVIDUAL_ADMIN_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', IndividualsFixture::INDIVIDUAL_ADMIN_ID)); + } +} diff --git a/tests/TestCase/Api/Organisations/AddOrganisationApiTest.php b/tests/TestCase/Api/Organisations/AddOrganisationApiTest.php new file mode 100644 index 0000000..5a47554 --- /dev/null +++ b/tests/TestCase/Api/Organisations/AddOrganisationApiTest.php @@ -0,0 +1,73 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'name' => 'Test Organisation', + 'description' => $faker->text, + 'uuid' => $uuid, + 'url' => 'http://example.com', + 'nationality' => 'US', + 'sector' => 'sector', + 'type' => 'type', + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"uuid": "%s"', $uuid)); + $this->assertDbRecordExists('Organisations', ['uuid' => $uuid]); + } + + public function testAddOrganisationNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'name' => 'Test Organisation', + 'description' => $faker->text, + 'uuid' => $uuid, + 'url' => 'http://example.com', + 'nationality' => 'US', + 'sector' => 'sector', + 'type' => 'type', + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('Organisations', ['uuid' => $uuid]); + } +} diff --git a/tests/TestCase/Api/Organisations/DeleteOrganisationApiTest.php b/tests/TestCase/Api/Organisations/DeleteOrganisationApiTest.php new file mode 100644 index 0000000..efdaa5c --- /dev/null +++ b/tests/TestCase/Api/Organisations/DeleteOrganisationApiTest.php @@ -0,0 +1,46 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_B_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('Organisations', ['id' => OrganisationsFixture::ORGANISATION_B_ID]); + } + + public function testDeleteOrganisationNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_B_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('Organisations', ['id' => OrganisationsFixture::ORGANISATION_B_ID]); + } +} diff --git a/tests/TestCase/Api/Organisations/EditOrganisationApiTest.php b/tests/TestCase/Api/Organisations/EditOrganisationApiTest.php new file mode 100644 index 0000000..6d14f3c --- /dev/null +++ b/tests/TestCase/Api/Organisations/EditOrganisationApiTest.php @@ -0,0 +1,69 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID); + $this->put( + $url, + [ + 'name' => 'Test Organisation 4321', + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists( + 'Organisations', + [ + 'id' => OrganisationsFixture::ORGANISATION_A_ID, + 'name' => 'Test Organisation 4321', + ] + ); + } + + public function testEditOrganisationNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_B_ID); + $this->put( + $url, + [ + 'name' => 'Test Organisation 1234' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists( + 'Organisations', + [ + 'id' => OrganisationsFixture::ORGANISATION_B_ID, + 'name' => 'Test Organisation 1234' + ] + ); + } +} diff --git a/tests/TestCase/Api/Organisations/IndexOrganisationsApiTest.php b/tests/TestCase/Api/Organisations/IndexOrganisationsApiTest.php new file mode 100644 index 0000000..a22e0f4 --- /dev/null +++ b/tests/TestCase/Api/Organisations/IndexOrganisationsApiTest.php @@ -0,0 +1,35 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', OrganisationsFixture::ORGANISATION_A_ID)); + $this->assertResponseContains(sprintf('"id": %d', OrganisationsFixture::ORGANISATION_B_ID)); + } +} diff --git a/tests/TestCase/Api/Organisations/TagOrganisationApiTest.php b/tests/TestCase/Api/Organisations/TagOrganisationApiTest.php new file mode 100644 index 0000000..f8bd194 --- /dev/null +++ b/tests/TestCase/Api/Organisations/TagOrganisationApiTest.php @@ -0,0 +1,74 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID); + $this->post( + $url, + [ + 'tag_list' => "[\"red\"]" + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists( + 'TagsTagged', + [ + 'tag_id' => TagsTagsFixture::TAG_RED_ID, + 'fk_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'fk_model' => 'Organisations' + ] + ); + } + + public function testTagOrganisationNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID); + $this->post( + $url, + [ + 'tag_list' => "[\"green\"]" + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists( + 'TagsTagged', + [ + 'tag_id' => TagsTagsFixture::TAG_GREEN_ID, + 'fk_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'fk_model' => 'Organisations' + ] + ); + } +} diff --git a/tests/TestCase/Api/Organisations/UntagOrganisationApiTest.php b/tests/TestCase/Api/Organisations/UntagOrganisationApiTest.php new file mode 100644 index 0000000..59f1bea --- /dev/null +++ b/tests/TestCase/Api/Organisations/UntagOrganisationApiTest.php @@ -0,0 +1,74 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID); + $this->post( + $url, + [ + 'tag_list' => "[\"org-a\"]" + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists( + 'TagsTagged', + [ + 'tag_id' => TagsTagsFixture::TAG_ORG_A_ID, + 'fk_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'fk_model' => 'Organisations' + ] + ); + } + + public function testUntagOrganisationNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID); + $this->post( + $url, + [ + 'tag_list' => "[\"org-a\"]" + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordExists( + 'TagsTagged', + [ + 'tag_id' => TagsTagsFixture::TAG_ORG_A_ID, + 'fk_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'fk_model' => 'Organisations' + ] + ); + } +} diff --git a/tests/TestCase/Api/Organisations/ViewOrganisationApiTest.php b/tests/TestCase/Api/Organisations/ViewOrganisationApiTest.php new file mode 100644 index 0000000..a9a728b --- /dev/null +++ b/tests/TestCase/Api/Organisations/ViewOrganisationApiTest.php @@ -0,0 +1,37 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains('"name": "Organisation A"'); + } +} diff --git a/tests/TestCase/Api/SharingGroups/AddSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/AddSharingGroupApiTest.php new file mode 100644 index 0000000..cbfebbb --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/AddSharingGroupApiTest.php @@ -0,0 +1,78 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'name' => 'Test Sharing Group', + 'releasability' => 'Test Sharing Group releasability', + 'description' => 'Test Sharing Group description', + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'active' => true, + 'local' => true + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"uuid": "%s"', $uuid)); + $this->assertDbRecordExists('SharingGroups', ['uuid' => $uuid]); + } + + public function testAddSharingGroupNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $faker = \Faker\Factory::create(); + $uuid = $faker->uuid; + + $this->post( + self::ENDPOINT, + [ + 'uuid' => $uuid, + 'name' => 'Test Sharing Group', + 'releasability' => 'Sharing Group A', + 'description' => 'Sharing Group A description', + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'user_id' => UsersFixture::USER_ADMIN_ID, + 'active' => true, + 'local' => true + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('SharingGroups', ['uuid' => $uuid]); + } +} diff --git a/tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php new file mode 100644 index 0000000..e2d1dc5 --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/DeleteSharingGroupApiTest.php @@ -0,0 +1,46 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('SharingGroups', ['id' => SharingGroupsFixture::SHARING_GROUP_A_ID]); + } + + public function testDeleteSharingGroupNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('SharingGroups', ['id' => SharingGroupsFixture::SHARING_GROUP_A_ID]); + } +} diff --git a/tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php new file mode 100644 index 0000000..07dff5b --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/EditSharingGroupApiTest.php @@ -0,0 +1,70 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->put( + $url, + [ + 'name' => 'Test Sharing Group 4321', + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists( + 'SharingGroups', + [ + 'id' => SharingGroupsFixture::SHARING_GROUP_A_ID, + 'name' => 'Test Sharing Group 4321', + ] + ); + } + + public function testEditSharingGroupNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_B_ID); + $this->put( + $url, + [ + 'name' => 'Test Sharing Group 1234' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists( + 'SharingGroups', + [ + 'id' => SharingGroupsFixture::SHARING_GROUP_B_ID, + 'name' => 'Test Sharing Group 1234' + ] + ); + } +} diff --git a/tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php b/tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php new file mode 100644 index 0000000..5286af2 --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/IndexSharingGroupsApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', SharingGroupsFixture::SHARING_GROUP_A_ID)); + $this->assertResponseContains(sprintf('"id": %d', SharingGroupsFixture::SHARING_GROUP_B_ID)); + } +} diff --git a/tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php b/tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php new file mode 100644 index 0000000..06ceb93 --- /dev/null +++ b/tests/TestCase/Api/SharingGroups/ViewSharingGroupApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, SharingGroupsFixture::SHARING_GROUP_A_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"id": %d', SharingGroupsFixture::SHARING_GROUP_A_ID)); + } +} diff --git a/tests/TestCase/Api/Tags/IndexTagsApiTest.php b/tests/TestCase/Api/Tags/IndexTagsApiTest.php new file mode 100644 index 0000000..4b13b67 --- /dev/null +++ b/tests/TestCase/Api/Tags/IndexTagsApiTest.php @@ -0,0 +1,36 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + + $this->assertResponseOk(); + $this->assertResponseContains('"name": "red"'); + $this->assertResponseContains('"name": "green"'); + $this->assertResponseContains('"name": "blue"'); + } +} diff --git a/tests/TestCase/Api/Users/AddUserApiTest.php b/tests/TestCase/Api/Users/AddUserApiTest.php new file mode 100644 index 0000000..3437d29 --- /dev/null +++ b/tests/TestCase/Api/Users/AddUserApiTest.php @@ -0,0 +1,66 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->post( + self::ENDPOINT, + [ + 'individual_id' => UsersFixture::USER_REGULAR_USER_ID, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'role_id' => RolesFixture::ROLE_REGULAR_USER_ID, + 'disabled' => false, + 'username' => 'test', + 'password' => 'Password123456!', + ] + ); + + $this->assertResponseOk(); + $this->assertResponseContains('"username": "test"'); + $this->assertDbRecordExists('Users', ['username' => 'test']); + } + + public function testAddUserNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $this->post( + self::ENDPOINT, + [ + 'individual_id' => UsersFixture::USER_REGULAR_USER_ID, + 'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID, + 'role_id' => RolesFixture::ROLE_REGULAR_USER_ID, + 'disabled' => false, + 'username' => 'test', + 'password' => 'Password123456!' + ] + ); + + $this->assertResponseCode(405); + $this->assertDbRecordNotExists('Users', ['username' => 'test']); + } +} diff --git a/tests/TestCase/Api/Users/ChangePasswordApiTest.php b/tests/TestCase/Api/Users/ChangePasswordApiTest.php new file mode 100644 index 0000000..201cb74 --- /dev/null +++ b/tests/TestCase/Api/Users/ChangePasswordApiTest.php @@ -0,0 +1,74 @@ +initializeOpenApiValidator(); + + $this->collection = new ComponentRegistry(); + $this->auth = new FormAuthenticate($this->collection, [ + 'userModel' => 'Users', + ]); + } + + public function testChangePasswordOwnUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $newPassword = 'Test12345678!'; + + $this->put( + self::ENDPOINT, + [ + 'password' => $newPassword, + ] + ); + + $this->assertResponseOk(); + + // Test new password with form login + $request = new ServerRequest([ + 'url' => 'users/login', + 'post' => [ + 'username' => UsersFixture::USER_REGULAR_USER_USERNAME, + 'password' => $newPassword + ], + ]); + $result = $this->auth->authenticate($request, new Response()); + + $this->assertEquals(UsersFixture::USER_REGULAR_USER_ID, $result['id']); + $this->assertEquals(UsersFixture::USER_REGULAR_USER_USERNAME, $result['username']); + } +} diff --git a/tests/TestCase/Api/Users/DeleteUserApiTest.php b/tests/TestCase/Api/Users/DeleteUserApiTest.php new file mode 100644 index 0000000..9288b9a --- /dev/null +++ b/tests/TestCase/Api/Users/DeleteUserApiTest.php @@ -0,0 +1,45 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_REGULAR_USER_ID); + $this->delete($url); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('Users', ['id' => UsersFixture::USER_REGULAR_USER_ID]); + } + + public function testDeleteUserNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_ORG_ADMIN_ID); + $this->delete($url); + + $this->assertResponseCode(405); + $this->assertDbRecordExists('Users', ['id' => UsersFixture::USER_ORG_ADMIN_ID]); + } +} diff --git a/tests/TestCase/Api/Users/EditUserApiTest.php b/tests/TestCase/Api/Users/EditUserApiTest.php new file mode 100644 index 0000000..dd685b9 --- /dev/null +++ b/tests/TestCase/Api/Users/EditUserApiTest.php @@ -0,0 +1,62 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_REGULAR_USER_ID); + $this->put( + $url, + [ + 'id' => UsersFixture::USER_REGULAR_USER_ID, + 'role_id' => RolesFixture::ROLE_ORG_ADMIN_ID, + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordExists('Users', [ + 'id' => UsersFixture::USER_REGULAR_USER_ID, + 'role_id' => RolesFixture::ROLE_ORG_ADMIN_ID + ]); + } + + public function testEditRoleNotAllowedAsRegularUser(): void + { + $this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY); + $this->put( + self::ENDPOINT, + [ + 'role_id' => RolesFixture::ROLE_ADMIN_ID, + ] + ); + + $this->assertResponseOk(); + $this->assertDbRecordNotExists('Users', [ + 'id' => UsersFixture::USER_REGULAR_USER_ID, + 'role_id' => RolesFixture::ROLE_ADMIN_ID + ]); + } +} diff --git a/tests/TestCase/Api/Users/IndexUsersApiTest.php b/tests/TestCase/Api/Users/IndexUsersApiTest.php new file mode 100644 index 0000000..c30462b --- /dev/null +++ b/tests/TestCase/Api/Users/IndexUsersApiTest.php @@ -0,0 +1,34 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME)); + } +} diff --git a/tests/TestCase/Api/Users/ViewUserApiTest.php b/tests/TestCase/Api/Users/ViewUserApiTest.php new file mode 100644 index 0000000..e3ab847 --- /dev/null +++ b/tests/TestCase/Api/Users/ViewUserApiTest.php @@ -0,0 +1,44 @@ +setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $this->get(self::ENDPOINT); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME)); + } + + public function testViewUserById(): void + { + $this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY); + $url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_REGULAR_USER_ID); + $this->get($url); + + $this->assertResponseOk(); + $this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_REGULAR_USER_USERNAME)); + } +} diff --git a/tests/TestCase/ApplicationTest.php b/tests/TestCase/ApplicationTest.php index cd09f1e..e2d3183 100644 --- a/tests/TestCase/ApplicationTest.php +++ b/tests/TestCase/ApplicationTest.php @@ -40,10 +40,14 @@ class ApplicationTest extends IntegrationTestCase $app->bootstrap(); $plugins = $app->getPlugins(); - $this->assertCount(3, $plugins); + $this->assertCount(7, $plugins); $this->assertSame('Bake', $plugins->get('Bake')->getName()); $this->assertSame('DebugKit', $plugins->get('DebugKit')->getName()); $this->assertSame('Migrations', $plugins->get('Migrations')->getName()); + $this->assertSame('Authentication', $plugins->get('Authentication')->getName()); + $this->assertSame('ADmad/SocialAuth', $plugins->get('ADmad/SocialAuth')->getName()); + $this->assertSame('Tags', $plugins->get('Tags')->getName()); + $this->assertSame('Cake/TwigView', $plugins->get('Cake/TwigView')->getName()); } /** diff --git a/tests/TestCase/Controller/PagesControllerTest.php b/tests/TestCase/Controller/PagesControllerTest.php deleted file mode 100644 index f2958f9..0000000 --- a/tests/TestCase/Controller/PagesControllerTest.php +++ /dev/null @@ -1,126 +0,0 @@ -get('/'); - $this->assertResponseOk(); - $this->get('/'); - $this->assertResponseOk(); - } - - /** - * testDisplay method - * - * @return void - */ - public function testDisplay() - { - $this->get('/pages/home'); - $this->assertResponseOk(); - $this->assertResponseContains('CakePHP'); - $this->assertResponseContains(''); - } - - /** - * Test that missing template renders 404 page in production - * - * @return void - */ - public function testMissingTemplate() - { - Configure::write('debug', false); - $this->get('/pages/not_existing'); - - $this->assertResponseError(); - $this->assertResponseContains('Error'); - } - - /** - * Test that missing template in debug mode renders missing_template error page - * - * @return void - */ - public function testMissingTemplateInDebug() - { - Configure::write('debug', true); - $this->get('/pages/not_existing'); - - $this->assertResponseFailure(); - $this->assertResponseContains('Missing Template'); - $this->assertResponseContains('Stacktrace'); - $this->assertResponseContains('not_existing.php'); - } - - /** - * Test directory traversal protection - * - * @return void - */ - public function testDirectoryTraversalProtection() - { - $this->get('/pages/../Layout/ajax'); - $this->assertResponseCode(403); - $this->assertResponseContains('Forbidden'); - } - - /** - * Test that CSRF protection is applied to page rendering. - * - * @reutrn void - */ - public function testCsrfAppliedError() - { - $this->post('/pages/home', ['hello' => 'world']); - - $this->assertResponseCode(403); - $this->assertResponseContains('CSRF'); - } - - /** - * Test that CSRF protection is applied to page rendering. - * - * @reutrn void - */ - public function testCsrfAppliedOk() - { - $this->enableCsrfToken(); - $this->post('/pages/home', ['hello' => 'world']); - - $this->assertResponseCode(200); - $this->assertResponseContains('CakePHP'); - } -} diff --git a/tests/TestCase/Controller/Users/UsersControllerTest.php b/tests/TestCase/Controller/Users/UsersControllerTest.php new file mode 100644 index 0000000..7ef6e4c --- /dev/null +++ b/tests/TestCase/Controller/Users/UsersControllerTest.php @@ -0,0 +1,32 @@ +enableCsrfToken(); + $this->enableSecurityToken(); + + $this->post('/users/login', [ + 'username' => UsersFixture::USER_ADMIN_USERNAME, + 'password' => UsersFixture::USER_ADMIN_PASSWORD, + ]); + + $this->assertSessionHasKey('authUser.uuid'); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 962815c..7523c28 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,5 @@ runMany([ + ['connection' => 'test'], + ['plugin' => 'Tags', 'connection' => 'test'], + ['plugin' => 'ADmad/SocialAuth', 'connection' => 'test'] + ]); +} else { + echo "[ * ] Skipping DB migrations ...\n"; +} + +$specFile = $_ENV['OPENAPI_SPEC'] ?? APP . '../webroot/docs/openapi.yaml'; +// Initialize OpenAPI spec validator +Configure::write('App.OpenAPIValidator', (new ValidatorBuilder)->fromYamlFile($specFile)); diff --git a/webroot/css/CodeMirror/codemirror-additional.css b/webroot/css/CodeMirror/codemirror-additional.css index 0c62e18..4399c1a 100644 --- a/webroot/css/CodeMirror/codemirror-additional.css +++ b/webroot/css/CodeMirror/codemirror-additional.css @@ -26,4 +26,8 @@ .CodeMirror-hints { z-index: 1060 !important; /* Make sure hint is above modal */ +} + +.CodeMirror pre.CodeMirror-placeholder { + color: #999; } \ No newline at end of file diff --git a/webroot/css/layout.css b/webroot/css/layout.css index 8016e00..84062b0 100644 --- a/webroot/css/layout.css +++ b/webroot/css/layout.css @@ -184,6 +184,13 @@ main.content { .global-search-container #globalSearch { padding-right: 26px; + width: 280px; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, width 0.3s; + -webkit-transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, width 0.3s; +} + +.global-search-container #globalSearch:focus { + width: 380px !important; } .top-navbar .global-search-container .search-input-container > i.icon { @@ -210,6 +217,11 @@ main.content { .sidebar-scroll { position: relative; width: 100%; + overflow-y: hidden; +} + +.sidebar-scroll:hover { + overflow-y: auto; } .sidebar-content { @@ -221,26 +233,63 @@ ul.sidebar-elements { padding: 0; } +.sidebar .lock-sidebar { + -webkit-box-shadow: 0px -1px 5px 1px rgb(0 0 0 / 8%); + box-shadow: 0px -1px 5px 1px rgb(0 0 0 / 8%); +} + .sidebar .lock-sidebar > a::before { content: "\f101"; font-family: 'Font Awesome 5 Free'; font-weight: 900; + transition: margin-left 0.1s ease-out; + margin-left: 0; } .sidebar.expanded .lock-sidebar > a::before { content: "\f100"; } +.sidebar .lock-sidebar:hover > a::before { + margin-left: 0.5rem; +} +.sidebar.expanded .lock-sidebar:hover > a::before { + margin-left: -0.5rem; +} + /* sidebar entry */ ul.sidebar-elements > li { list-style: none; } +ul.sidebar-elements > li > a[data-href] { + cursor: pointer; +} + +ul.sidebar-elements li.bookmarks { + padding: 0 calc((var(--sidebar-width-collapsed) - 25px) / 2); +} + .sidebar.expanded ul.sidebar-elements li > a.sidebar-link, .sidebar:hover ul.sidebar-elements li > a.sidebar-link { text-overflow: ellipsis; } +.sidebar ul.sidebar-elements li.bookmark-categ, +.sidebar ul.sidebar-elements li.bookmarks { + display: none; +} + +.sidebar.expanded ul.sidebar-elements li.bookmark-categ, +.sidebar:hover ul.sidebar-elements li.bookmark-categ { + display: flex; +} + +.sidebar.expanded ul.sidebar-elements li.bookmarks, +.sidebar:hover ul.sidebar-elements li.bookmarks { + display: list-item; +} + ul.sidebar-elements li > a.sidebar-link { position: relative; display: block; @@ -419,7 +468,7 @@ ul.sidebar-elements > li.category > span.category-divider > hr { } .center-navbar nav.header-breadcrumb li.header-breadcrumb-item { - max-width: 200px; + max-width: 25vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -476,11 +525,13 @@ ul.sidebar-elements > li.category > span.category-divider > hr { mask-repeat: no-repeat; mask-size: contain, cover; mask-composite: source-out; + mask-composite: subtract; -webkit-mask-image: url(/img/icon-composition/sheet-all.svg), url(/img/icon-composition/z.svg); -webkit-mask-position: 0 0, 2.4px calc((var(--navbar-height) - 10px) / 2); -webkit-mask-repeat: no-repeat; -webkit-mask-size: contain, cover; -webkit-mask-composite: source-out; + -webkit-mask-composite: subtract; transition-timing-function: ease-out; transition-duration: 0.2s; transition-property: -webkit-mask-position; diff --git a/webroot/css/login.css b/webroot/css/login.css index f308579..7cfb32d 100644 --- a/webroot/css/login.css +++ b/webroot/css/login.css @@ -30,7 +30,7 @@ body { transform: rotate(100deg); -webkit-transform-origin: center; transform-origin: center; - left: 42%; + left: calc(50% - 120px); top: 30%; } diff --git a/webroot/css/main.css b/webroot/css/main.css index 3b78fff..562e523 100644 --- a/webroot/css/main.css +++ b/webroot/css/main.css @@ -58,6 +58,10 @@ line-height: 1.5; } +.cursor-pointer { + cursor: pointer; +} + .link-unstyled, .link-unstyled:link, .link-unstyled:hover { color: inherit; text-decoration: inherit; @@ -90,7 +94,7 @@ input[type="checkbox"]:disabled.change-cursor { } .select2-container { - z-index: 1056; + z-index: 900; } .select2-container--bootstrap-5 { @@ -98,15 +102,16 @@ input[type="checkbox"]:disabled.change-cursor { } .grow-on-hover { - -webkit-transition: -webkit-transform 0.5s cubic-bezier(0, 0.90, 0.35, 1.00); - -moz-transition: -moz-transform 0.5s cubic-bezier(0, 0.90, 0.35, 1.00); - transition: all .2s cubic-bezier(0, 0.90, 0.35, 1.00); + -webkit-transition: all 0.2s ease-out; + -moz-transition: all 0.2s ease-out; + transition: all .2s ease-out; + transform-style: preserve-3d; } .grow-on-hover:hover { - -webkit-transform: translateZ(0) scale(1.02, 1.02); - -moz-transform: translateZ(0) scale(1.02, 1.02); - transform: translateZ(0) scale(1.02, 1.02); + -webkit-transform: translateZ(0) scale(1.05); + -moz-transform: translateZ(0) scale(1.05); + transform: translateZ(0) scale(1.05); box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 15%) !important; } @@ -126,4 +131,40 @@ input[type="checkbox"]:disabled.change-cursor { @keyframes slide-in { 50% { opacity: 0.3; } 100% { transform: translateX(0%); opacity: 1; } -} \ No newline at end of file +} + +.trends-arrow-up-black { + display: inline-flex; + min-width: 1em; + min-height: 0.71em; + position: relative; +} +.trends-arrow-up-black::before { + position: absolute; + width: 100%; + height: 100%; + content: " "; + background-size: contain; + background-repeat: no-repeat; + background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8' standalone='no'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='223.995' width='383.98752' viewBox='0 0 383.98752 223.995' role='img'%3E%3Cpath d='m 367.9975,0 h -118.06 c -21.38,0 -32.09,25.85 -16.97,40.97 l 32.4,32.4 -73.37,73.38 -73.37,-73.37 c -12.5,-12.5 -32.76,-12.5 -45.25,0 l -68.69,68.69 c -6.25,6.25 -6.25,16.38 0,22.63 l 22.62,22.62 c 6.25,6.25 16.38,6.25 22.63,0 l 46.06,-46.07 73.37,73.37 c 12.5,12.5 32.76,12.5 45.25,0 l 96,-96 32.4,32.4 c 15.12,15.12 40.97,4.41 40.97,-16.97 V 16 c 0.01,-8.84 -7.15,-16 -15.99,-16 z' /%3E%3C/svg%3E%0A");.97,-16.97 V 16 c 0.01,-8.84 -7.15,-16 -15.99,-16 z' /%3E%3C/svg%3E%0A"); +} + +.trends-arrow-up-white { + display: inline-flex; + min-width: 1em; + min-height: 0.71em; + position: relative; +} +.trends-arrow-up-white::before { + background-color: #fff; + position: absolute; + width: 100%; + height: 100%; + content: " "; + mask-size: contain; + mask-repeat: no-repeat; + mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8' standalone='no'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='223.995' width='383.98752' viewBox='0 0 383.98752 223.995' role='img'%3E%3Cpath d='m 367.9975,0 h -118.06 c -21.38,0 -32.09,25.85 -16.97,40.97 l 32.4,32.4 -73.37,73.38 -73.37,-73.37 c -12.5,-12.5 -32.76,-12.5 -45.25,0 l -68.69,68.69 c -6.25,6.25 -6.25,16.38 0,22.63 l 22.62,22.62 c 6.25,6.25 16.38,6.25 22.63,0 l 46.06,-46.07 73.37,73.37 c 12.5,12.5 32.76,12.5 45.25,0 l 96,-96 32.4,32.4 c 15.12,15.12 40.97,4.41 40.97,-16.97 V 16 c 0.01,-8.84 -7.15,-16 -15.99,-16 z' /%3E%3C/svg%3E%0A"); + -webkit-mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8' standalone='no'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='223.995' width='383.98752' viewBox='0 0 383.98752 223.995' role='img'%3E%3Cpath d='m 367.9975,0 h -118.06 c -21.38,0 -32.09,25.85 -16.97,40.97 l 32.4,32.4 -73.37,73.38 -73.37,-73.37 c -12.5,-12.5 -32.76,-12.5 -45.25,0 l -68.69,68.69 c -6.25,6.25 -6.25,16.38 0,22.63 l 22.62,22.62 c 6.25,6.25 16.38,6.25 22.63,0 l 46.06,-46.07 73.37,73.37 c 12.5,12.5 32.76,12.5 45.25,0 l 96,-96 32.4,32.4 c 15.12,15.12 40.97,4.41 40.97,-16.97 V 16 c 0.01,-8.84 -7.15,-16 -15.99,-16 z' /%3E%3C/svg%3E%0A"); +} diff --git a/webroot/css/themes/additional/bootstrap-additional.css b/webroot/css/themes/additional/bootstrap-additional.css index 4a7c905..1a992d8 100644 --- a/webroot/css/themes/additional/bootstrap-additional.css +++ b/webroot/css/themes/additional/bootstrap-additional.css @@ -1,284 +1,463 @@ /* Callout */ .callout { border: 1px solid #e9ecef; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #fff; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .callout-primary { border-left-color: #0d6efd; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #6c757d; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #198754; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #0dcaf0; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #ffc107; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #dc3545; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #f8f9fa; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #212529; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #04214c; background-color: #b6d4fe; - border-color: #9ec5fe; } - .toast-primary strong { - border-top-color: #85b6fe; } + border-color: #9ec5fe; +} +.toast-primary strong { + border-top-color: #85b6fe; +} .toast-secondary { color: #202326; background-color: #d3d6d8; - border-color: #c4c8cb; } - .toast-secondary strong { - border-top-color: #b6bbbf; } + border-color: #c4c8cb; +} +.toast-secondary strong { + border-top-color: #b6bbbf; +} .toast-success { color: #082919; background-color: #badbcc; - border-color: #a3cfbb; } - .toast-success strong { - border-top-color: #92c6af; } + border-color: #a3cfbb; +} +.toast-success strong { + border-top-color: #92c6af; +} .toast-info { color: #043d48; background-color: #b6effb; - border-color: #9eeaf9; } - .toast-info strong { - border-top-color: #86e5f8; } + border-color: #9eeaf9; +} +.toast-info strong { + border-top-color: #86e5f8; +} .toast-warning { color: #4d3a02; background-color: #ffecb5; - border-color: #ffe69c; } - .toast-warning strong { - border-top-color: #ffe083; } + border-color: #ffe69c; +} +.toast-warning strong { + border-top-color: #ffe083; +} .toast-danger { color: #421015; background-color: #f5c2c7; - border-color: #f1aeb5; } - .toast-danger strong { - border-top-color: #ed98a1; } + border-color: #f1aeb5; +} +.toast-danger strong { + border-top-color: #ed98a1; +} .toast-light { color: #4a4b4b; background-color: #fdfdfe; - border-color: #fcfdfd; } - .toast-light strong { - border-top-color: #edf3f3; } + border-color: #fcfdfd; +} +.toast-light strong { + border-top-color: #edf3f3; +} .toast-dark { color: #0a0b0c; background-color: #bcbebf; - border-color: #a6a8a9; } - .toast-dark strong { - border-top-color: #999b9c; } + border-color: #a6a8a9; +} +.toast-dark strong { + border-top-color: #999b9c; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #0d6efd; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #0b5ed7; } +======= + background-color: #0d6efd; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #0d6efd; } - + background-color: #0d6efd; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #6c757d; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #5c636a; } +======= + background-color: #6c757d; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #6c757d; } - + background-color: #6c757d; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #198754; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #157347; } +======= + background-color: #198754; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #198754; } - + background-color: #198754; +} .dropdown-item.dropdown-item-info { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #0dcaf0; } + .dropdown-item.dropdown-item-info:hover { + color: #000; + background-color: #31d2f2; } +======= + background-color: #0dcaf0; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #000; - background-color: #0dcaf0; } - + background-color: #0dcaf0; +} .dropdown-item.dropdown-item-warning { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #ffc107; } + .dropdown-item.dropdown-item-warning:hover { + color: #000; + background-color: #ffca2c; } +======= + background-color: #ffc107; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #000; - background-color: #ffc107; } - + background-color: #ffc107; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #dc3545; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #bb2d3b; } +======= + background-color: #dc3545; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #dc3545; } - + background-color: #dc3545; +} .dropdown-item.dropdown-item-light { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #f8f9fa; } + .dropdown-item.dropdown-item-light:hover { + color: #000; + background-color: #f9fafb; } +======= + background-color: #f8f9fa; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #000; - background-color: #f8f9fa; } - + background-color: #f8f9fa; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #212529; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #1c1f23; } +======= + background-color: #212529; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #212529; } + background-color: #212529; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%230dcaf0' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #0dcaf0; - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%230dcaf0' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #0dcaf0; + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #ffc107; - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #ffc107; + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%230dcaf0'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-check-input.is-invalid.info { - border-color: #0dcaf0; } - + border-color: #0dcaf0; +} .form-check-input.is-invalid.info:checked { - background-color: #0dcaf0; } - + background-color: #0dcaf0; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(13, 202, 240, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(13, 202, 240, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #ffc107; } - + border-color: #ffc107; +} .form-check-input.is-invalid.warning:checked { - background-color: #ffc107; } - + background-color: #ffc107; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; +<<<<<<< HEAD transform: translateX(-50%) translateY(-50%); } + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #6c757d; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #6c757d; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } +======= + transform: translateX(-50%) translateY(-50%); +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f diff --git a/webroot/css/themes/theme-darkly.css b/webroot/css/themes/theme-darkly.css index 9c4511a..1243863 100644 --- a/webroot/css/themes/theme-darkly.css +++ b/webroot/css/themes/theme-darkly.css @@ -1,287 +1,462 @@ /* Callout */ .callout { border: 1px solid 1px solid none; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #363636; - box-shadow: none; } + box-shadow: none; +} .callout-primary { border-left-color: #375a7f; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #444; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #00bc8c; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #3498db; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #f39c12; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #e74c3c; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #adb5bd; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #303030; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #111b26; background-color: #c3ced9; - border-color: #afbdcc; } - .toast-primary strong { - border-top-color: #9fb0c2; } + border-color: #afbdcc; +} +.toast-primary strong { + border-top-color: #9fb0c2; +} .toast-secondary { color: #141414; background-color: #c7c7c7; - border-color: #b4b4b4; } - .toast-secondary strong { - border-top-color: #a7a7a7; } + border-color: #b4b4b4; +} +.toast-secondary strong { + border-top-color: #a7a7a7; +} .toast-success { color: #00382a; background-color: #b3ebdd; - border-color: #99e4d1; } - .toast-success strong { - border-top-color: #85dfc8; } + border-color: #99e4d1; +} +.toast-success strong { + border-top-color: #85dfc8; +} .toast-info { color: #102e42; background-color: #c2e0f4; - border-color: #aed6f1; } - .toast-info strong { - border-top-color: #98cbed; } + border-color: #aed6f1; +} +.toast-info strong { + border-top-color: #98cbed; +} .toast-warning { color: #492f05; background-color: #fbe1b8; - border-color: #fad7a0; } - .toast-warning strong { - border-top-color: #f9cd88; } + border-color: #fad7a0; +} +.toast-warning strong { + border-top-color: #f9cd88; +} .toast-danger { color: #451712; background-color: #f8c9c5; - border-color: #f5b7b1; } - .toast-danger strong { - border-top-color: #f2a29a; } + border-color: #f5b7b1; +} +.toast-danger strong { + border-top-color: #f2a29a; +} .toast-light { color: #343639; background-color: #e6e9eb; - border-color: #dee1e5; } - .toast-light strong { - border-top-color: #d0d4da; } + border-color: #dee1e5; +} +.toast-light strong { + border-top-color: #d0d4da; +} .toast-dark { color: #0e0e0e; background-color: #c1c1c1; - border-color: #acacac; } - .toast-dark strong { - border-top-color: #9f9f9f; } + border-color: #acacac; +} +.toast-dark strong { + border-top-color: #9f9f9f; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #375a7f; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #2f4d6c; } +======= + background-color: #375a7f; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #375a7f; } - + background-color: #375a7f; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #444; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #3a3a3a; } +======= + background-color: #444; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #444; } - + background-color: #444; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #00bc8c; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #00a077; } +======= + background-color: #00bc8c; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #00bc8c; } - + background-color: #00bc8c; +} .dropdown-item.dropdown-item-info { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #3498db; } + .dropdown-item.dropdown-item-info:hover { + color: #fff; + background-color: #2c81ba; } +======= + background-color: #3498db; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #fff; - background-color: #3498db; } - + background-color: #3498db; +} .dropdown-item.dropdown-item-warning { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #f39c12; } + .dropdown-item.dropdown-item-warning:hover { + color: #fff; + background-color: #cf850f; } +======= + background-color: #f39c12; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #fff; - background-color: #f39c12; } - + background-color: #f39c12; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #e74c3c; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #c44133; } +======= + background-color: #e74c3c; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #e74c3c; } - + background-color: #e74c3c; +} .dropdown-item.dropdown-item-light { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #adb5bd; } + .dropdown-item.dropdown-item-light:hover { + color: #fff; + background-color: #939aa1; } +======= + background-color: #adb5bd; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #fff; - background-color: #adb5bd; } - + background-color: #adb5bd; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #303030; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #292929; } +======= + background-color: #303030; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #303030; } + background-color: #303030; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%233498db' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #3498db; - box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%233498db' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #3498db; + box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f39c12' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #f39c12; - box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f39c12' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #f39c12; + box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%233498db'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23f39c12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); +} .form-check-input.is-invalid.info { - border-color: #3498db; } - + border-color: #3498db; +} .form-check-input.is-invalid.info:checked { - background-color: #3498db; } - + background-color: #3498db; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #f39c12; } - + border-color: #f39c12; +} .form-check-input.is-invalid.warning:checked { - background-color: #f39c12; } - + background-color: #f39c12; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(243, 156, 18, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(243, 156, 18, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #444; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #444; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ body { @@ -290,87 +465,114 @@ body { /* background by SVGBackgrounds.com */ background-attachment: fixed; background-size: cover; - background-blend-mode: soft-light; } + background-blend-mode: soft-light; +} .panel { background-color: #363636; border: 1px solid #454545; - box-shadow: none; } + box-shadow: none; +} .loading-overlay { background-color: #222; - opacity: 0.65; } + opacity: 0.65; +} /* Top navbar */ .top-navbar { - background-color: #375a7f; } + background-color: #375a7f; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #adb5bd; } + background-color: #adb5bd; +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: none; - background-color: #444; } + background-color: #444; +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid none; } + border-right: 1px solid none; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #fff; } + color: #fff; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #595f64; - color: #fff; } + color: #fff; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #595f64; - color: #fff; } + color: #fff; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: var(--cerebrate-color); } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #60676c; - color: #fff; } + color: #fff; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #60676c; } + background-color: #60676c; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: var(--cerebrate-color); } + background-color: var(--cerebrate-color); +} .lock-sidebar > a.btn { - background-color: unset; } + background-color: unset; +} diff --git a/webroot/css/themes/theme-default.css b/webroot/css/themes/theme-default.css index d826d86..7ee279e 100644 --- a/webroot/css/themes/theme-default.css +++ b/webroot/css/themes/theme-default.css @@ -1,287 +1,462 @@ /* Callout */ .callout { border: 1px solid #e9ecef; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #fff; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .callout-primary { border-left-color: #0d6efd; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #6c757d; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #198754; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #0dcaf0; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #ffc107; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #dc3545; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #f8f9fa; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #212529; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #04214c; background-color: #b6d4fe; - border-color: #9ec5fe; } - .toast-primary strong { - border-top-color: #85b6fe; } + border-color: #9ec5fe; +} +.toast-primary strong { + border-top-color: #85b6fe; +} .toast-secondary { color: #202326; background-color: #d3d6d8; - border-color: #c4c8cb; } - .toast-secondary strong { - border-top-color: #b6bbbf; } + border-color: #c4c8cb; +} +.toast-secondary strong { + border-top-color: #b6bbbf; +} .toast-success { color: #082919; background-color: #badbcc; - border-color: #a3cfbb; } - .toast-success strong { - border-top-color: #92c6af; } + border-color: #a3cfbb; +} +.toast-success strong { + border-top-color: #92c6af; +} .toast-info { color: #043d48; background-color: #b6effb; - border-color: #9eeaf9; } - .toast-info strong { - border-top-color: #86e5f8; } + border-color: #9eeaf9; +} +.toast-info strong { + border-top-color: #86e5f8; +} .toast-warning { color: #4d3a02; background-color: #ffecb5; - border-color: #ffe69c; } - .toast-warning strong { - border-top-color: #ffe083; } + border-color: #ffe69c; +} +.toast-warning strong { + border-top-color: #ffe083; +} .toast-danger { color: #421015; background-color: #f5c2c7; - border-color: #f1aeb5; } - .toast-danger strong { - border-top-color: #ed98a1; } + border-color: #f1aeb5; +} +.toast-danger strong { + border-top-color: #ed98a1; +} .toast-light { color: #4a4b4b; background-color: #fdfdfe; - border-color: #fcfdfd; } - .toast-light strong { - border-top-color: #edf3f3; } + border-color: #fcfdfd; +} +.toast-light strong { + border-top-color: #edf3f3; +} .toast-dark { color: #0a0b0c; background-color: #bcbebf; - border-color: #a6a8a9; } - .toast-dark strong { - border-top-color: #999b9c; } + border-color: #a6a8a9; +} +.toast-dark strong { + border-top-color: #999b9c; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #0d6efd; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #0b5ed7; } +======= + background-color: #0d6efd; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #0d6efd; } - + background-color: #0d6efd; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #6c757d; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #5c636a; } +======= + background-color: #6c757d; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #6c757d; } - + background-color: #6c757d; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #198754; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #157347; } +======= + background-color: #198754; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #198754; } - + background-color: #198754; +} .dropdown-item.dropdown-item-info { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #0dcaf0; } + .dropdown-item.dropdown-item-info:hover { + color: #000; + background-color: #31d2f2; } +======= + background-color: #0dcaf0; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #000; - background-color: #0dcaf0; } - + background-color: #0dcaf0; +} .dropdown-item.dropdown-item-warning { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #ffc107; } + .dropdown-item.dropdown-item-warning:hover { + color: #000; + background-color: #ffca2c; } +======= + background-color: #ffc107; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #000; - background-color: #ffc107; } - + background-color: #ffc107; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #dc3545; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #bb2d3b; } +======= + background-color: #dc3545; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #dc3545; } - + background-color: #dc3545; +} .dropdown-item.dropdown-item-light { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #f8f9fa; } + .dropdown-item.dropdown-item-light:hover { + color: #000; + background-color: #f9fafb; } +======= + background-color: #f8f9fa; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #000; - background-color: #f8f9fa; } - + background-color: #f8f9fa; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #212529; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #1c1f23; } +======= + background-color: #212529; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #212529; } + background-color: #212529; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%230dcaf0' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #0dcaf0; - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%230dcaf0' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #0dcaf0; + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #ffc107; - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #ffc107; + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%230dcaf0'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-check-input.is-invalid.info { - border-color: #0dcaf0; } - + border-color: #0dcaf0; +} .form-check-input.is-invalid.info:checked { - background-color: #0dcaf0; } - + background-color: #0dcaf0; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(13, 202, 240, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(13, 202, 240, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #ffc107; } - + border-color: #ffc107; +} .form-check-input.is-invalid.warning:checked { - background-color: #ffc107; } - + background-color: #ffc107; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #6c757d; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #6c757d; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ body { @@ -290,87 +465,114 @@ body { /* background by SVGBackgrounds.com */ background-attachment: fixed; background-size: cover; - background-blend-mode: normal; } + background-blend-mode: normal; +} .panel { background-color: #fff; border: none; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .loading-overlay { background-color: #f8f9fa; - opacity: 0.75; } + opacity: 0.75; +} /* Top navbar */ .top-navbar { - background-color: #212529; } + background-color: #212529; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #f8f9fa; } + background-color: #f8f9fa; +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #f8f9fa; } + background-color: #f8f9fa; +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid #ddd; } + border-right: 1px solid #ddd; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #000; } + color: #000; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #dbdbdb; - color: #000; } + color: #000; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #dbdbdb; - color: #000; } + color: #000; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: var(--cerebrate-color); } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #ebebeb; - color: #000; } + color: #000; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #ebebeb; } + background-color: #ebebeb; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: var(--cerebrate-color); } + background-color: var(--cerebrate-color); +} .lock-sidebar > a.btn { - background-color: #f8f9fa; } + background-color: #f8f9fa; +} diff --git a/webroot/css/themes/theme-flatly.css b/webroot/css/themes/theme-flatly.css index c94d649..3bd3ec9 100644 --- a/webroot/css/themes/theme-flatly.css +++ b/webroot/css/themes/theme-flatly.css @@ -1,287 +1,462 @@ /* Callout */ .callout { border: 1px solid #ecf0f1; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #fff; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .callout-primary { border-left-color: #2c3e50; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #95a5a6; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #18bc9c; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #3498db; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #f39c12; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #e74c3c; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #ecf0f1; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #7b8a8b; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #0d1318; background-color: #c0c5cb; - border-color: #abb2b9; } - .toast-primary strong { - border-top-color: #9da5ad; } + border-color: #abb2b9; +} +.toast-primary strong { + border-top-color: #9da5ad; +} .toast-secondary { color: #2d3232; background-color: #dfe4e4; - border-color: #d5dbdb; } - .toast-secondary strong { - border-top-color: #c7cfcf; } + border-color: #d5dbdb; +} +.toast-secondary strong { + border-top-color: #c7cfcf; +} .toast-success { color: #07382f; background-color: #baebe1; - border-color: #a3e4d7; } - .toast-success strong { - border-top-color: #8fdece; } + border-color: #a3e4d7; +} +.toast-success strong { + border-top-color: #8fdece; +} .toast-info { color: #102e42; background-color: #c2e0f4; - border-color: #aed6f1; } - .toast-info strong { - border-top-color: #98cbed; } + border-color: #aed6f1; +} +.toast-info strong { + border-top-color: #98cbed; +} .toast-warning { color: #492f05; background-color: #fbe1b8; - border-color: #fad7a0; } - .toast-warning strong { - border-top-color: #f9cd88; } + border-color: #fad7a0; +} +.toast-warning strong { + border-top-color: #f9cd88; +} .toast-danger { color: #451712; background-color: #f8c9c5; - border-color: #f5b7b1; } - .toast-danger strong { - border-top-color: #f2a29a; } + border-color: #f5b7b1; +} +.toast-danger strong { + border-top-color: #f2a29a; +} .toast-light { color: #474848; background-color: #f9fbfb; - border-color: #f7f9f9; } - .toast-light strong { - border-top-color: #e8eeee; } + border-color: #f7f9f9; +} +.toast-light strong { + border-top-color: #e8eeee; +} .toast-dark { color: #25292a; background-color: #d7dcdc; - border-color: #cad0d1; } - .toast-dark strong { - border-top-color: #bcc4c5; } + border-color: #cad0d1; +} +.toast-dark strong { + border-top-color: #bcc4c5; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #2c3e50; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #253544; } +======= + background-color: #2c3e50; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #2c3e50; } - + background-color: #2c3e50; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #95a5a6; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #7f8c8d; } +======= + background-color: #95a5a6; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #95a5a6; } - + background-color: #95a5a6; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #18bc9c; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #14a085; } +======= + background-color: #18bc9c; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #18bc9c; } - + background-color: #18bc9c; +} .dropdown-item.dropdown-item-info { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #3498db; } + .dropdown-item.dropdown-item-info:hover { + color: #fff; + background-color: #2c81ba; } +======= + background-color: #3498db; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #fff; - background-color: #3498db; } - + background-color: #3498db; +} .dropdown-item.dropdown-item-warning { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #f39c12; } + .dropdown-item.dropdown-item-warning:hover { + color: #fff; + background-color: #cf850f; } +======= + background-color: #f39c12; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #fff; - background-color: #f39c12; } - + background-color: #f39c12; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #e74c3c; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #c44133; } +======= + background-color: #e74c3c; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #e74c3c; } - + background-color: #e74c3c; +} .dropdown-item.dropdown-item-light { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #ecf0f1; } + .dropdown-item.dropdown-item-light:hover { + color: #000; + background-color: #eff2f3; } +======= + background-color: #ecf0f1; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #000; - background-color: #ecf0f1; } - + background-color: #ecf0f1; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #7b8a8b; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #697576; } +======= + background-color: #7b8a8b; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #7b8a8b; } + background-color: #7b8a8b; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%233498db' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #3498db; - box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%233498db' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #3498db; + box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f39c12' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #f39c12; - box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f39c12' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #f39c12; + box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%233498db'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23f39c12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); +} .form-check-input.is-invalid.info { - border-color: #3498db; } - + border-color: #3498db; +} .form-check-input.is-invalid.info:checked { - background-color: #3498db; } - + background-color: #3498db; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #f39c12; } - + border-color: #f39c12; +} .form-check-input.is-invalid.warning:checked { - background-color: #f39c12; } - + background-color: #f39c12; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(243, 156, 18, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(243, 156, 18, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #95a5a6; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #95a5a6; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ body { @@ -290,87 +465,114 @@ body { /* background by SVGBackgrounds.com */ background-attachment: fixed; background-size: cover; - background-blend-mode: normal; } + background-blend-mode: normal; +} .panel { background-color: #fff; border: none; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .loading-overlay { background-color: #ecf0f1; - opacity: 0.75; } + opacity: 0.75; +} /* Top navbar */ .top-navbar { - background-color: #2c3e50; } + background-color: #2c3e50; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #ecf0f1; } + background-color: #ecf0f1; +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: none; - background-color: #ecf0f1; } + background-color: #ecf0f1; +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid none; } + border-right: 1px solid none; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #000; } + color: #000; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #dbdbdb; - color: #18bc9c; } + color: #18bc9c; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #dbdbdb; - color: #18bc9c; } + color: #18bc9c; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: #18bc9c; } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #ebebeb; - color: #18bc9c; } + color: #18bc9c; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #ebebeb; } + background-color: #ebebeb; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: #18bc9c; } + background-color: #18bc9c; +} .lock-sidebar > a.btn { - background-color: unset; } + background-color: unset; +} diff --git a/webroot/css/themes/theme-minty.css b/webroot/css/themes/theme-minty.css index 6948503..512ab02 100644 --- a/webroot/css/themes/theme-minty.css +++ b/webroot/css/themes/theme-minty.css @@ -1,287 +1,462 @@ /* Callout */ .callout { border: 1px solid #ecf0f1; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #fff; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .callout-primary { border-left-color: #2c3e50; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #95a5a6; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #18bc9c; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #3498db; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #f39c12; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #e74c3c; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #ecf0f1; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #7b8a8b; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #0d1318; background-color: #c0c5cb; - border-color: #abb2b9; } - .toast-primary strong { - border-top-color: #9da5ad; } + border-color: #abb2b9; +} +.toast-primary strong { + border-top-color: #9da5ad; +} .toast-secondary { color: #2d3232; background-color: #dfe4e4; - border-color: #d5dbdb; } - .toast-secondary strong { - border-top-color: #c7cfcf; } + border-color: #d5dbdb; +} +.toast-secondary strong { + border-top-color: #c7cfcf; +} .toast-success { color: #07382f; background-color: #baebe1; - border-color: #a3e4d7; } - .toast-success strong { - border-top-color: #8fdece; } + border-color: #a3e4d7; +} +.toast-success strong { + border-top-color: #8fdece; +} .toast-info { color: #102e42; background-color: #c2e0f4; - border-color: #aed6f1; } - .toast-info strong { - border-top-color: #98cbed; } + border-color: #aed6f1; +} +.toast-info strong { + border-top-color: #98cbed; +} .toast-warning { color: #492f05; background-color: #fbe1b8; - border-color: #fad7a0; } - .toast-warning strong { - border-top-color: #f9cd88; } + border-color: #fad7a0; +} +.toast-warning strong { + border-top-color: #f9cd88; +} .toast-danger { color: #451712; background-color: #f8c9c5; - border-color: #f5b7b1; } - .toast-danger strong { - border-top-color: #f2a29a; } + border-color: #f5b7b1; +} +.toast-danger strong { + border-top-color: #f2a29a; +} .toast-light { color: #474848; background-color: #f9fbfb; - border-color: #f7f9f9; } - .toast-light strong { - border-top-color: #e8eeee; } + border-color: #f7f9f9; +} +.toast-light strong { + border-top-color: #e8eeee; +} .toast-dark { color: #25292a; background-color: #d7dcdc; - border-color: #cad0d1; } - .toast-dark strong { - border-top-color: #bcc4c5; } + border-color: #cad0d1; +} +.toast-dark strong { + border-top-color: #bcc4c5; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #2c3e50; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #253544; } +======= + background-color: #2c3e50; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #2c3e50; } - + background-color: #2c3e50; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #95a5a6; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #7f8c8d; } +======= + background-color: #95a5a6; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #95a5a6; } - + background-color: #95a5a6; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #18bc9c; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #14a085; } +======= + background-color: #18bc9c; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #18bc9c; } - + background-color: #18bc9c; +} .dropdown-item.dropdown-item-info { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #3498db; } + .dropdown-item.dropdown-item-info:hover { + color: #fff; + background-color: #2c81ba; } +======= + background-color: #3498db; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #fff; - background-color: #3498db; } - + background-color: #3498db; +} .dropdown-item.dropdown-item-warning { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #f39c12; } + .dropdown-item.dropdown-item-warning:hover { + color: #fff; + background-color: #cf850f; } +======= + background-color: #f39c12; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #fff; - background-color: #f39c12; } - + background-color: #f39c12; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #e74c3c; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #c44133; } +======= + background-color: #e74c3c; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #e74c3c; } - + background-color: #e74c3c; +} .dropdown-item.dropdown-item-light { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #ecf0f1; } + .dropdown-item.dropdown-item-light:hover { + color: #000; + background-color: #eff2f3; } +======= + background-color: #ecf0f1; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #000; - background-color: #ecf0f1; } - + background-color: #ecf0f1; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #7b8a8b; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #697576; } +======= + background-color: #7b8a8b; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #7b8a8b; } + background-color: #7b8a8b; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%233498db' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #3498db; - box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%233498db' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #3498db; + box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f39c12' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #f39c12; - box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f39c12' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #f39c12; + box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%233498db'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%233498db' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23f39c12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f39c12' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(243, 156, 18, 0.25); +} .form-check-input.is-invalid.info { - border-color: #3498db; } - + border-color: #3498db; +} .form-check-input.is-invalid.info:checked { - background-color: #3498db; } - + background-color: #3498db; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #f39c12; } - + border-color: #f39c12; +} .form-check-input.is-invalid.warning:checked { - background-color: #f39c12; } - + background-color: #f39c12; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(243, 156, 18, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(243, 156, 18, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #95a5a6; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #95a5a6; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ body { @@ -290,87 +465,114 @@ body { /* background by SVGBackgrounds.com */ background-attachment: fixed; background-size: cover; - background-blend-mode: normal; } + background-blend-mode: normal; +} .panel { background-color: #fff; border: none; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .loading-overlay { background-color: #ecf0f1; - opacity: 0.65; } + opacity: 0.65; +} /* Top navbar */ .top-navbar { - background-color: #2c3e50; } + background-color: #2c3e50; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #ecf0f1; } + background-color: #ecf0f1; +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: none; - background-color: #ecf0f1; } + background-color: #ecf0f1; +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid none; } + border-right: 1px solid none; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #343a40; } + color: #343a40; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #dbdbdb; - color: #18bc9c; } + color: #18bc9c; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #dbdbdb; - color: #18bc9c; } + color: #18bc9c; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: #18bc9c; } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #ebebeb; - color: #18bc9c; } + color: #18bc9c; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #ebebeb; } + background-color: #ebebeb; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: #18bc9c; } + background-color: #18bc9c; +} .lock-sidebar > a.btn { - background-color: unset; } + background-color: unset; +} diff --git a/webroot/css/themes/theme-quartz.css b/webroot/css/themes/theme-quartz.css index 71469f2..c676d28 100644 --- a/webroot/css/themes/theme-quartz.css +++ b/webroot/css/themes/theme-quartz.css @@ -1,371 +1,572 @@ /* Callout */ .callout { border: 1px solid #e9e9e8; - border-radius: .25rem; + border-radius: 0.25rem; background-color: transparent; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .callout-primary { border-left-color: #e83283; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: rgba(255, 255, 255, 0.4); - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #41d7a7; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #39cbfb; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #ffc107; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #fd7e14; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #e9e9e8; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #212529; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #460f27; background-color: #f8c2da; - border-color: #f6adcd; } - .toast-primary strong { - border-top-color: #f396bf; } + border-color: #f6adcd; +} +.toast-primary strong { + border-top-color: #f396bf; +} .toast-secondary { color: rgba(25, 25, 25, 0.82); background-color: rgba(255, 255, 255, 0.82); - border-color: rgba(255, 255, 255, 0.76); } - .toast-secondary strong { - border-top-color: rgba(242, 242, 242, 0.76); } + border-color: rgba(255, 255, 255, 0.76); +} +.toast-secondary strong { + border-top-color: rgba(242, 242, 242, 0.76); +} .toast-success { color: #144132; background-color: #c6f3e5; - border-color: #b3efdc; } - .toast-success strong { - border-top-color: #9eebd2; } + border-color: #b3efdc; +} +.toast-success strong { + border-top-color: #9eebd2; +} .toast-info { color: #113d4b; background-color: #c4effe; - border-color: #b0eafd; } - .toast-info strong { - border-top-color: #97e3fc; } + border-color: #b0eafd; +} +.toast-info strong { + border-top-color: #97e3fc; +} .toast-warning { color: #4d3a02; background-color: #ffecb5; - border-color: #ffe69c; } - .toast-warning strong { - border-top-color: #ffe083; } + border-color: #ffe69c; +} +.toast-warning strong { + border-top-color: #ffe083; +} .toast-danger { color: #4c2606; background-color: #fed8b9; - border-color: #fecba1; } - .toast-danger strong { - border-top-color: #febd88; } + border-color: #fecba1; +} +.toast-danger strong { + border-top-color: #febd88; +} .toast-light { color: #464646; background-color: #f8f8f8; - border-color: #f6f6f6; } - .toast-light strong { - border-top-color: #e9e9e9; } + border-color: #f6f6f6; +} +.toast-light strong { + border-top-color: #e9e9e9; +} .toast-dark { color: #0a0b0c; background-color: #bcbebf; - border-color: #a6a8a9; } - .toast-dark strong { - border-top-color: #999b9c; } + border-color: #a6a8a9; +} +.toast-dark strong { + border-top-color: #999b9c; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #e83283; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #c52b6f; } +======= + background-color: #e83283; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #e83283; } - + background-color: #e83283; +} .dropdown-item.dropdown-item-secondary { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: rgba(255, 255, 255, 0.4); } + .dropdown-item.dropdown-item-secondary:hover { + color: #000; + background-color: rgba(255, 255, 255, 0.49); } +======= + background-color: rgba(255, 255, 255, 0.4); +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #000; - background-color: rgba(255, 255, 255, 0.4); } - + background-color: rgba(255, 255, 255, 0.4); +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #41d7a7; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #37b78e; } +======= + background-color: #41d7a7; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #41d7a7; } - + background-color: #41d7a7; +} .dropdown-item.dropdown-item-info { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #39cbfb; } + .dropdown-item.dropdown-item-info:hover { + color: #fff; + background-color: #30add5; } +======= + background-color: #39cbfb; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #fff; - background-color: #39cbfb; } - + background-color: #39cbfb; +} .dropdown-item.dropdown-item-warning { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #ffc107; } + .dropdown-item.dropdown-item-warning:hover { + color: #fff; + background-color: #d9a406; } +======= + background-color: #ffc107; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #fff; - background-color: #ffc107; } - + background-color: #ffc107; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #fd7e14; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #d76b11; } +======= + background-color: #fd7e14; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #fd7e14; } - + background-color: #fd7e14; +} .dropdown-item.dropdown-item-light { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #e9e9e8; } + .dropdown-item.dropdown-item-light:hover { + color: #000; + background-color: #ececeb; } +======= + background-color: #e9e9e8; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #000; - background-color: #e9e9e8; } - + background-color: #e9e9e8; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #212529; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #1c1f23; } +======= + background-color: #212529; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #212529; } + background-color: #212529; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2339cbfb' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%2339cbfb' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #39cbfb; - box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2339cbfb' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%2339cbfb' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #39cbfb; + box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #ffc107; - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #ffc107; + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%2339cbfb'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%2339cbfb' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-check-input.is-invalid.info { - border-color: #39cbfb; } - + border-color: #39cbfb; +} .form-check-input.is-invalid.info:checked { - background-color: #39cbfb; } - + background-color: #39cbfb; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(57, 203, 251, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(57, 203, 251, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #ffc107; } - + border-color: #ffc107; +} .form-check-input.is-invalid.warning:checked { - background-color: #ffc107; } - + background-color: #ffc107; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: rgba(255, 255, 255, 0.4); + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: rgba(255, 255, 255, 0.4); + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ .panel { background-color: transparent; border: none; - box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); } + box-shadow: 0 0 35px 0 rgba(154, 161, 171, 0.25); +} .loading-overlay { background-color: #e9e9e8; - opacity: 0.35; } + opacity: 0.35; +} /* Top navbar */ .top-navbar { - background-color: #e83283; } + background-color: #e83283; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: rgba(255, 255, 255, 0.4); } + background-color: rgba(255, 255, 255, 0.4); +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: none; - background-color: rgba(255, 255, 255, 0.4); } + background-color: rgba(255, 255, 255, 0.4); +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid none; } + border-right: 1px solid none; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #fff; } + color: #fff; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #fff; - color: #343a40; } + color: #343a40; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #fff; - color: #343a40; } + color: #343a40; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: #e83283; } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #fff; - color: #343a40; } + color: #343a40; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #fff; } + background-color: #fff; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: #e83283; } + background-color: #e83283; +} .lock-sidebar > a.btn { - background-color: rgba(255, 255, 255, 0.4); } + background-color: rgba(255, 255, 255, 0.4); +} .btn { display: inline-block; @@ -382,427 +583,485 @@ ul.sidebar-elements li > a.sidebar-link.active::after { padding: 0.75rem 1.5rem; font-size: 1rem; border-radius: 0.5rem; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .btn { - transition: none; } } - .btn:hover { - color: #fff; } - .btn-check:focus + .btn, .btn:focus { - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(232, 50, 131, 0.25); } - .btn:disabled, .btn.disabled, - fieldset:disabled .btn { - pointer-events: none; - opacity: 0.65; } + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: #fff; +} +.btn-check:focus + .btn, .btn:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(232, 50, 131, 0.25); +} +.btn:disabled, .btn.disabled, fieldset:disabled .btn { + pointer-events: none; + opacity: 0.65; +} .btn-primary { color: #fff; background-color: #e83283; - border-color: #e83283; } - .btn-primary:hover { - color: #fff; - background-color: #c52b6f; - border-color: #ba2869; } - .btn-check:focus + .btn-primary, .btn-primary:focus { - color: #fff; - background-color: #c52b6f; - border-color: #ba2869; - box-shadow: 0 0 0 0.25rem rgba(235, 81, 150, 0.5); } - .btn-check:checked + .btn-primary, - .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, - .show > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #ba2869; - border-color: #ae2662; } - .btn-check:checked + .btn-primary:focus, - .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, - .show > .btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(235, 81, 150, 0.5); } - .btn-primary:disabled, .btn-primary.disabled { - color: #fff; - background-color: #e83283; - border-color: #e83283; } + border-color: #e83283; +} +.btn-primary:hover { + color: #fff; + background-color: #c52b6f; + border-color: #ba2869; +} +.btn-check:focus + .btn-primary, .btn-primary:focus { + color: #fff; + background-color: #c52b6f; + border-color: #ba2869; + box-shadow: 0 0 0 0.25rem rgba(235, 81, 150, 0.5); +} +.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #ba2869; + border-color: #ae2662; +} +.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(235, 81, 150, 0.5); +} +.btn-primary:disabled, .btn-primary.disabled { + color: #fff; + background-color: #e83283; + border-color: #e83283; +} .btn-secondary { color: #000; background-color: rgba(255, 255, 255, 0.4); - border-color: rgba(255, 255, 255, 0.4); } - .btn-secondary:hover { - color: #000; - background-color: rgba(255, 255, 255, 0.49); - border-color: rgba(255, 255, 255, 0.46); } - .btn-check:focus + .btn-secondary, .btn-secondary:focus { - color: #000; - background-color: rgba(255, 255, 255, 0.49); - border-color: rgba(255, 255, 255, 0.46); - box-shadow: 0 0 0 0.25rem rgba(149, 149, 149, 0.5); } - .btn-check:checked + .btn-secondary, - .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, - .show > .btn-secondary.dropdown-toggle { - color: #000; - background-color: rgba(255, 255, 255, 0.52); - border-color: rgba(255, 255, 255, 0.46); } - .btn-check:checked + .btn-secondary:focus, - .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, - .show > .btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(149, 149, 149, 0.5); } - .btn-secondary:disabled, .btn-secondary.disabled { - color: #000; - background-color: rgba(255, 255, 255, 0.4); - border-color: rgba(255, 255, 255, 0.4); } + border-color: rgba(255, 255, 255, 0.4); +} +.btn-secondary:hover { + color: #000; + background-color: rgba(255, 255, 255, 0.49); + border-color: rgba(255, 255, 255, 0.46); +} +.btn-check:focus + .btn-secondary, .btn-secondary:focus { + color: #000; + background-color: rgba(255, 255, 255, 0.49); + border-color: rgba(255, 255, 255, 0.46); + box-shadow: 0 0 0 0.25rem rgba(149, 149, 149, 0.5); +} +.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle { + color: #000; + background-color: rgba(255, 255, 255, 0.52); + border-color: rgba(255, 255, 255, 0.46); +} +.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(149, 149, 149, 0.5); +} +.btn-secondary:disabled, .btn-secondary.disabled { + color: #000; + background-color: rgba(255, 255, 255, 0.4); + border-color: rgba(255, 255, 255, 0.4); +} .btn-success { color: #fff; background-color: #41d7a7; - border-color: #41d7a7; } - .btn-success:hover { - color: #fff; - background-color: #37b78e; - border-color: #34ac86; } - .btn-check:focus + .btn-success, .btn-success:focus { - color: #fff; - background-color: #37b78e; - border-color: #34ac86; - box-shadow: 0 0 0 0.25rem rgba(94, 221, 180, 0.5); } - .btn-check:checked + .btn-success, - .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, - .show > .btn-success.dropdown-toggle { - color: #fff; - background-color: #34ac86; - border-color: #31a17d; } - .btn-check:checked + .btn-success:focus, - .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, - .show > .btn-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(94, 221, 180, 0.5); } - .btn-success:disabled, .btn-success.disabled { - color: #fff; - background-color: #41d7a7; - border-color: #41d7a7; } + border-color: #41d7a7; +} +.btn-success:hover { + color: #fff; + background-color: #37b78e; + border-color: #34ac86; +} +.btn-check:focus + .btn-success, .btn-success:focus { + color: #fff; + background-color: #37b78e; + border-color: #34ac86; + box-shadow: 0 0 0 0.25rem rgba(94, 221, 180, 0.5); +} +.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #34ac86; + border-color: #31a17d; +} +.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(94, 221, 180, 0.5); +} +.btn-success:disabled, .btn-success.disabled { + color: #fff; + background-color: #41d7a7; + border-color: #41d7a7; +} .btn-info { color: #fff; background-color: #39cbfb; - border-color: #39cbfb; } - .btn-info:hover { - color: #fff; - background-color: #30add5; - border-color: #2ea2c9; } - .btn-check:focus + .btn-info, .btn-info:focus { - color: #fff; - background-color: #30add5; - border-color: #2ea2c9; - box-shadow: 0 0 0 0.25rem rgba(87, 211, 252, 0.5); } - .btn-check:checked + .btn-info, - .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, - .show > .btn-info.dropdown-toggle { - color: #fff; - background-color: #2ea2c9; - border-color: #2b98bc; } - .btn-check:checked + .btn-info:focus, - .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, - .show > .btn-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(87, 211, 252, 0.5); } - .btn-info:disabled, .btn-info.disabled { - color: #fff; - background-color: #39cbfb; - border-color: #39cbfb; } + border-color: #39cbfb; +} +.btn-info:hover { + color: #fff; + background-color: #30add5; + border-color: #2ea2c9; +} +.btn-check:focus + .btn-info, .btn-info:focus { + color: #fff; + background-color: #30add5; + border-color: #2ea2c9; + box-shadow: 0 0 0 0.25rem rgba(87, 211, 252, 0.5); +} +.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #2ea2c9; + border-color: #2b98bc; +} +.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(87, 211, 252, 0.5); +} +.btn-info:disabled, .btn-info.disabled { + color: #fff; + background-color: #39cbfb; + border-color: #39cbfb; +} .btn-warning { color: #fff; background-color: #ffc107; - border-color: #ffc107; } - .btn-warning:hover { - color: #fff; - background-color: #d9a406; - border-color: #cc9a06; } - .btn-check:focus + .btn-warning, .btn-warning:focus { - color: #fff; - background-color: #d9a406; - border-color: #cc9a06; - box-shadow: 0 0 0 0.25rem rgba(255, 202, 44, 0.5); } - .btn-check:checked + .btn-warning, - .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, - .show > .btn-warning.dropdown-toggle { - color: #fff; - background-color: #cc9a06; - border-color: #bf9105; } - .btn-check:checked + .btn-warning:focus, - .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, - .show > .btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 202, 44, 0.5); } - .btn-warning:disabled, .btn-warning.disabled { - color: #fff; - background-color: #ffc107; - border-color: #ffc107; } + border-color: #ffc107; +} +.btn-warning:hover { + color: #fff; + background-color: #d9a406; + border-color: #cc9a06; +} +.btn-check:focus + .btn-warning, .btn-warning:focus { + color: #fff; + background-color: #d9a406; + border-color: #cc9a06; + box-shadow: 0 0 0 0.25rem rgba(255, 202, 44, 0.5); +} +.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #cc9a06; + border-color: #bf9105; +} +.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 202, 44, 0.5); +} +.btn-warning:disabled, .btn-warning.disabled { + color: #fff; + background-color: #ffc107; + border-color: #ffc107; +} .btn-danger { color: #fff; background-color: #fd7e14; - border-color: #fd7e14; } - .btn-danger:hover { - color: #fff; - background-color: #d76b11; - border-color: #ca6510; } - .btn-check:focus + .btn-danger, .btn-danger:focus { - color: #fff; - background-color: #d76b11; - border-color: #ca6510; - box-shadow: 0 0 0 0.25rem rgba(253, 145, 55, 0.5); } - .btn-check:checked + .btn-danger, - .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, - .show > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #ca6510; - border-color: #be5f0f; } - .btn-check:checked + .btn-danger:focus, - .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, - .show > .btn-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(253, 145, 55, 0.5); } - .btn-danger:disabled, .btn-danger.disabled { - color: #fff; - background-color: #fd7e14; - border-color: #fd7e14; } + border-color: #fd7e14; +} +.btn-danger:hover { + color: #fff; + background-color: #d76b11; + border-color: #ca6510; +} +.btn-check:focus + .btn-danger, .btn-danger:focus { + color: #fff; + background-color: #d76b11; + border-color: #ca6510; + box-shadow: 0 0 0 0.25rem rgba(253, 145, 55, 0.5); +} +.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #ca6510; + border-color: #be5f0f; +} +.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(253, 145, 55, 0.5); +} +.btn-danger:disabled, .btn-danger.disabled { + color: #fff; + background-color: #fd7e14; + border-color: #fd7e14; +} .btn-light { color: #000; background-color: #e9e9e8; - border-color: #e9e9e8; } - .btn-light:hover { - color: #000; - background-color: #ececeb; - border-color: #ebebea; } - .btn-check:focus + .btn-light, .btn-light:focus { - color: #000; - background-color: #ececeb; - border-color: #ebebea; - box-shadow: 0 0 0 0.25rem rgba(198, 198, 197, 0.5); } - .btn-check:checked + .btn-light, - .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, - .show > .btn-light.dropdown-toggle { - color: #000; - background-color: #ededed; - border-color: #ebebea; } - .btn-check:checked + .btn-light:focus, - .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, - .show > .btn-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(198, 198, 197, 0.5); } - .btn-light:disabled, .btn-light.disabled { - color: #000; - background-color: #e9e9e8; - border-color: #e9e9e8; } + border-color: #e9e9e8; +} +.btn-light:hover { + color: #000; + background-color: #ececeb; + border-color: #ebebea; +} +.btn-check:focus + .btn-light, .btn-light:focus { + color: #000; + background-color: #ececeb; + border-color: #ebebea; + box-shadow: 0 0 0 0.25rem rgba(198, 198, 197, 0.5); +} +.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle { + color: #000; + background-color: #ededed; + border-color: #ebebea; +} +.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(198, 198, 197, 0.5); +} +.btn-light:disabled, .btn-light.disabled { + color: #000; + background-color: #e9e9e8; + border-color: #e9e9e8; +} .btn-dark { color: #fff; background-color: #212529; - border-color: #212529; } - .btn-dark:hover { - color: #fff; - background-color: #1c1f23; - border-color: #1a1e21; } - .btn-check:focus + .btn-dark, .btn-dark:focus { - color: #fff; - background-color: #1c1f23; - border-color: #1a1e21; - box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); } - .btn-check:checked + .btn-dark, - .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, - .show > .btn-dark.dropdown-toggle { - color: #fff; - background-color: #1a1e21; - border-color: #191c1f; } - .btn-check:checked + .btn-dark:focus, - .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, - .show > .btn-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); } - .btn-dark:disabled, .btn-dark.disabled { - color: #fff; - background-color: #212529; - border-color: #212529; } + border-color: #212529; +} +.btn-dark:hover { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; +} +.btn-check:focus + .btn-dark, .btn-dark:focus { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +} +.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1e21; + border-color: #191c1f; +} +.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +} +.btn-dark:disabled, .btn-dark.disabled { + color: #fff; + background-color: #212529; + border-color: #212529; +} .btn-outline-primary { color: #e83283; - border-color: #e83283; } - .btn-outline-primary:hover { - color: #fff; - background-color: #e83283; - border-color: #e83283; } - .btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { - box-shadow: 0 0 0 0.25rem rgba(232, 50, 131, 0.5); } - .btn-check:checked + .btn-outline-primary, - .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { - color: #fff; - background-color: #e83283; - border-color: #e83283; } - .btn-check:checked + .btn-outline-primary:focus, - .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(232, 50, 131, 0.5); } - .btn-outline-primary:disabled, .btn-outline-primary.disabled { - color: #e83283; - background-color: transparent; } + border-color: #e83283; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #e83283; + border-color: #e83283; +} +.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { + box-shadow: 0 0 0 0.25rem rgba(232, 50, 131, 0.5); +} +.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { + color: #fff; + background-color: #e83283; + border-color: #e83283; +} +.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(232, 50, 131, 0.5); +} +.btn-outline-primary:disabled, .btn-outline-primary.disabled { + color: #e83283; + background-color: transparent; +} .btn-outline-secondary { color: rgba(255, 255, 255, 0.4); - border-color: rgba(255, 255, 255, 0.4); } - .btn-outline-secondary:hover { - color: #000; - background-color: rgba(255, 255, 255, 0.4); - border-color: rgba(255, 255, 255, 0.4); } - .btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.5); } - .btn-check:checked + .btn-outline-secondary, - .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { - color: #000; - background-color: rgba(255, 255, 255, 0.4); - border-color: rgba(255, 255, 255, 0.4); } - .btn-check:checked + .btn-outline-secondary:focus, - .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.5); } - .btn-outline-secondary:disabled, .btn-outline-secondary.disabled { - color: rgba(255, 255, 255, 0.4); - background-color: transparent; } + border-color: rgba(255, 255, 255, 0.4); +} +.btn-outline-secondary:hover { + color: #000; + background-color: rgba(255, 255, 255, 0.4); + border-color: rgba(255, 255, 255, 0.4); +} +.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.5); +} +.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { + color: #000; + background-color: rgba(255, 255, 255, 0.4); + border-color: rgba(255, 255, 255, 0.4); +} +.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.5); +} +.btn-outline-secondary:disabled, .btn-outline-secondary.disabled { + color: rgba(255, 255, 255, 0.4); + background-color: transparent; +} .btn-outline-success { color: #41d7a7; - border-color: #41d7a7; } - .btn-outline-success:hover { - color: #fff; - background-color: #41d7a7; - border-color: #41d7a7; } - .btn-check:focus + .btn-outline-success, .btn-outline-success:focus { - box-shadow: 0 0 0 0.25rem rgba(65, 215, 167, 0.5); } - .btn-check:checked + .btn-outline-success, - .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { - color: #fff; - background-color: #41d7a7; - border-color: #41d7a7; } - .btn-check:checked + .btn-outline-success:focus, - .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(65, 215, 167, 0.5); } - .btn-outline-success:disabled, .btn-outline-success.disabled { - color: #41d7a7; - background-color: transparent; } + border-color: #41d7a7; +} +.btn-outline-success:hover { + color: #fff; + background-color: #41d7a7; + border-color: #41d7a7; +} +.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { + box-shadow: 0 0 0 0.25rem rgba(65, 215, 167, 0.5); +} +.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { + color: #fff; + background-color: #41d7a7; + border-color: #41d7a7; +} +.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(65, 215, 167, 0.5); +} +.btn-outline-success:disabled, .btn-outline-success.disabled { + color: #41d7a7; + background-color: transparent; +} .btn-outline-info { color: #39cbfb; - border-color: #39cbfb; } - .btn-outline-info:hover { - color: #fff; - background-color: #39cbfb; - border-color: #39cbfb; } - .btn-check:focus + .btn-outline-info, .btn-outline-info:focus { - box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.5); } - .btn-check:checked + .btn-outline-info, - .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { - color: #fff; - background-color: #39cbfb; - border-color: #39cbfb; } - .btn-check:checked + .btn-outline-info:focus, - .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.5); } - .btn-outline-info:disabled, .btn-outline-info.disabled { - color: #39cbfb; - background-color: transparent; } + border-color: #39cbfb; +} +.btn-outline-info:hover { + color: #fff; + background-color: #39cbfb; + border-color: #39cbfb; +} +.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { + box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.5); +} +.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { + color: #fff; + background-color: #39cbfb; + border-color: #39cbfb; +} +.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(57, 203, 251, 0.5); +} +.btn-outline-info:disabled, .btn-outline-info.disabled { + color: #39cbfb; + background-color: transparent; +} .btn-outline-warning { color: #ffc107; - border-color: #ffc107; } - .btn-outline-warning:hover { - color: #fff; - background-color: #ffc107; - border-color: #ffc107; } - .btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); } - .btn-check:checked + .btn-outline-warning, - .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { - color: #fff; - background-color: #ffc107; - border-color: #ffc107; } - .btn-check:checked + .btn-outline-warning:focus, - .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); } - .btn-outline-warning:disabled, .btn-outline-warning.disabled { - color: #ffc107; - background-color: transparent; } + border-color: #ffc107; +} +.btn-outline-warning:hover { + color: #fff; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); +} +.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { + color: #fff; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); +} +.btn-outline-warning:disabled, .btn-outline-warning.disabled { + color: #ffc107; + background-color: transparent; +} .btn-outline-danger { color: #fd7e14; - border-color: #fd7e14; } - .btn-outline-danger:hover { - color: #fff; - background-color: #fd7e14; - border-color: #fd7e14; } - .btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { - box-shadow: 0 0 0 0.25rem rgba(253, 126, 20, 0.5); } - .btn-check:checked + .btn-outline-danger, - .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { - color: #fff; - background-color: #fd7e14; - border-color: #fd7e14; } - .btn-check:checked + .btn-outline-danger:focus, - .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(253, 126, 20, 0.5); } - .btn-outline-danger:disabled, .btn-outline-danger.disabled { - color: #fd7e14; - background-color: transparent; } + border-color: #fd7e14; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #fd7e14; + border-color: #fd7e14; +} +.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { + box-shadow: 0 0 0 0.25rem rgba(253, 126, 20, 0.5); +} +.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { + color: #fff; + background-color: #fd7e14; + border-color: #fd7e14; +} +.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(253, 126, 20, 0.5); +} +.btn-outline-danger:disabled, .btn-outline-danger.disabled { + color: #fd7e14; + background-color: transparent; +} .btn-outline-light { color: #e9e9e8; - border-color: #e9e9e8; } - .btn-outline-light:hover { - color: #000; - background-color: #e9e9e8; - border-color: #e9e9e8; } - .btn-check:focus + .btn-outline-light, .btn-outline-light:focus { - box-shadow: 0 0 0 0.25rem rgba(233, 233, 232, 0.5); } - .btn-check:checked + .btn-outline-light, - .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { - color: #000; - background-color: #e9e9e8; - border-color: #e9e9e8; } - .btn-check:checked + .btn-outline-light:focus, - .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(233, 233, 232, 0.5); } - .btn-outline-light:disabled, .btn-outline-light.disabled { - color: #e9e9e8; - background-color: transparent; } + border-color: #e9e9e8; +} +.btn-outline-light:hover { + color: #000; + background-color: #e9e9e8; + border-color: #e9e9e8; +} +.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { + box-shadow: 0 0 0 0.25rem rgba(233, 233, 232, 0.5); +} +.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { + color: #000; + background-color: #e9e9e8; + border-color: #e9e9e8; +} +.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(233, 233, 232, 0.5); +} +.btn-outline-light:disabled, .btn-outline-light.disabled { + color: #e9e9e8; + background-color: transparent; +} .btn-outline-dark { color: #212529; - border-color: #212529; } - .btn-outline-dark:hover { - color: #fff; - background-color: #212529; - border-color: #212529; } - .btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { - box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); } - .btn-check:checked + .btn-outline-dark, - .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { - color: #fff; - background-color: #212529; - border-color: #212529; } - .btn-check:checked + .btn-outline-dark:focus, - .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); } - .btn-outline-dark:disabled, .btn-outline-dark.disabled { - color: #212529; - background-color: transparent; } + border-color: #212529; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); +} +.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); +} +.btn-outline-dark:disabled, .btn-outline-dark.disabled { + color: #212529; + background-color: transparent; +} .btn-link { font-weight: 400; color: #fff; - text-decoration: underline; } - .btn-link:hover { - color: #cccccc; } - .btn-link:disabled, .btn-link.disabled { - color: #6c757d; } + text-decoration: underline; +} +.btn-link:hover { + color: #cccccc; +} +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} .btn-lg { padding: 0.5rem 1rem; font-size: 1.25rem; - border-radius: 0.7rem; } + border-radius: 0.7rem; +} .btn-sm { padding: 0.25rem 0.5rem; font-size: 0.875rem; - border-radius: 0.6rem; } + border-radius: 0.6rem; +} diff --git a/webroot/css/themes/theme-slate.css b/webroot/css/themes/theme-slate.css index d8b5ba6..ff30587 100644 --- a/webroot/css/themes/theme-slate.css +++ b/webroot/css/themes/theme-slate.css @@ -1,283 +1,462 @@ /* Callout */ .callout { border: 1px solid #e9ecef; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #363636; - box-shadow: none; } + box-shadow: none; +} .callout-primary { border-left-color: #3a3f44; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #7a8288; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #62c462; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #5bc0de; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #f89406; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #ee5f5b; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #e9ecef; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #272b30; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #111314; background-color: #c4c5c7; - border-color: #b0b2b4; } - .toast-primary strong { - border-top-color: #a3a5a8; } + border-color: #b0b2b4; +} +.toast-primary strong { + border-top-color: #a3a5a8; +} .toast-secondary { color: #252729; background-color: #d7dadb; - border-color: #cacdcf; } - .toast-secondary strong { - border-top-color: #bdc0c3; } + border-color: #cacdcf; +} +.toast-secondary strong { + border-top-color: #bdc0c3; +} .toast-success { color: #1d3b1d; background-color: #d0edd0; - border-color: #c0e7c0; } - .toast-success strong { - border-top-color: #aee0ae; } + border-color: #c0e7c0; +} +.toast-success strong { + border-top-color: #aee0ae; +} .toast-info { color: #1b3a43; background-color: #ceecf5; - border-color: #bde6f2; } - .toast-info strong { - border-top-color: #a8deee; } + border-color: #bde6f2; +} +.toast-info strong { + border-top-color: #a8deee; +} .toast-warning { color: #4a2c02; background-color: #fddfb4; - border-color: #fcd49b; } - .toast-warning strong { - border-top-color: #fbc982; } + border-color: #fcd49b; +} +.toast-warning strong { + border-top-color: #fbc982; +} .toast-danger { color: #471d1b; background-color: #facfce; - border-color: #f8bfbd; } - .toast-danger strong { - border-top-color: #f6a9a6; } + border-color: #f8bfbd; +} +.toast-danger strong { + border-top-color: #f6a9a6; +} .toast-light { color: #464748; background-color: #f8f9fa; - border-color: #f6f7f9; } - .toast-light strong { - border-top-color: #e7e9ef; } + border-color: #f6f7f9; +} +.toast-light strong { + border-top-color: #e7e9ef; +} .toast-dark { color: #0c0d0e; background-color: #bebfc1; - border-color: #a9aaac; } - .toast-dark strong { - border-top-color: #9c9d9f; } + border-color: #a9aaac; +} +.toast-dark strong { + border-top-color: #9c9d9f; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #3a3f44; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #31363a; } +======= + background-color: #3a3f44; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #3a3f44; } - + background-color: #3a3f44; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #7a8288; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #686f74; } +======= + background-color: #7a8288; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #7a8288; } - + background-color: #7a8288; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #62c462; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #53a753; } +======= + background-color: #62c462; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #62c462; } - + background-color: #62c462; +} .dropdown-item.dropdown-item-info { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #5bc0de; } + .dropdown-item.dropdown-item-info:hover { + color: #fff; + background-color: #4da3bd; } +======= + background-color: #5bc0de; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #fff; - background-color: #5bc0de; } - + background-color: #5bc0de; +} .dropdown-item.dropdown-item-warning { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #f89406; } + .dropdown-item.dropdown-item-warning:hover { + color: #fff; + background-color: #d37e05; } +======= + background-color: #f89406; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #fff; - background-color: #f89406; } - + background-color: #f89406; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #ee5f5b; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #ca514d; } +======= + background-color: #ee5f5b; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #ee5f5b; } - + background-color: #ee5f5b; +} .dropdown-item.dropdown-item-light { color: #000; text-decoration: none; +<<<<<<< HEAD background-color: #e9ecef; } + .dropdown-item.dropdown-item-light:hover { + color: #000; + background-color: #eceff1; } +======= + background-color: #e9ecef; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #000; - background-color: #e9ecef; } - + background-color: #e9ecef; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #272b30; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #212529; } +======= + background-color: #272b30; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #272b30; } + background-color: #272b30; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%235bc0de' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%235bc0de' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #5bc0de; - box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%235bc0de' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%235bc0de' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #5bc0de; + box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f89406' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f89406' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #f89406; - box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23f89406' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f89406' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #f89406; + box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, .form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%235bc0de'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%235bc0de' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, .form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23f89406'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f89406' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.25); +} .form-check-input.is-invalid.info { - border-color: #5bc0de; } - + border-color: #5bc0de; +} .form-check-input.is-invalid.info:checked { - background-color: #5bc0de; } - + background-color: #5bc0de; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(91, 192, 222, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #f89406; } - + border-color: #f89406; +} .form-check-input.is-invalid.warning:checked { - background-color: #f89406; } - + background-color: #f89406; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(248, 148, 6, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(248, 148, 6, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #7a8288; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #7a8288; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ body { @@ -286,90 +465,117 @@ body { /* background by SVGBackgrounds.com */ background-attachment: fixed; background-size: cover; - background-blend-mode: normal; } + background-blend-mode: normal; +} .panel { background-color: #363636; border: 1px solid #454545; - box-shadow: none; } + box-shadow: none; +} .loading-overlay { background-color: #272b30; - opacity: 0.65; } + opacity: 0.65; +} /* Top navbar */ .top-navbar { - background-color: #3a3f44; } + background-color: #3a3f44; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #e9ecef; } + background-color: #e9ecef; +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: none; - background-color: #7a8288; } + background-color: #7a8288; +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid none; } + border-right: 1px solid none; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #fff; } + color: #fff; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #595f64; - color: #fff; } + color: #fff; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #595f64; - color: #fff; } + color: #fff; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: var(--cerebrate-color); } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #60676c; - color: #fff; } + color: #fff; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #60676c; } + background-color: #60676c; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: var(--cerebrate-color); } + background-color: var(--cerebrate-color); +} .lock-sidebar > a.btn { - background-color: #7a8288; } + background-color: #7a8288; +} .btn { display: inline-block; @@ -386,455 +592,518 @@ ul.sidebar-elements li > a.sidebar-link.active::after { padding: 0.375rem 0.75rem; font-size: 1rem; border-radius: 0.25rem; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .btn { - transition: none; } } - .btn:hover { - color: #aaa; } - .btn-check:focus + .btn, .btn:focus { - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); } - .btn:disabled, .btn.disabled, - fieldset:disabled .btn { - pointer-events: none; - opacity: 0.65; } + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: #aaa; +} +.btn-check:focus + .btn, .btn:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); +} +.btn:disabled, .btn.disabled, fieldset:disabled .btn { + pointer-events: none; + opacity: 0.65; +} .btn-primary { color: #fff; background-color: #3a3f44; - border-color: #3a3f44; } - .btn-primary:hover { - color: #fff; - background-color: #31363a; - border-color: #2e3236; } - .btn-check:focus + .btn-primary, .btn-primary:focus { - color: #fff; - background-color: #31363a; - border-color: #2e3236; - box-shadow: 0 0 0 0.25rem rgba(88, 92, 96, 0.5); } - .btn-check:checked + .btn-primary, - .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, - .show > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #2e3236; - border-color: #2c2f33; } - .btn-check:checked + .btn-primary:focus, - .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, - .show > .btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(88, 92, 96, 0.5); } - .btn-primary:disabled, .btn-primary.disabled { - color: #fff; - background-color: #3a3f44; - border-color: #3a3f44; } + border-color: #3a3f44; +} +.btn-primary:hover { + color: #fff; + background-color: #31363a; + border-color: #2e3236; +} +.btn-check:focus + .btn-primary, .btn-primary:focus { + color: #fff; + background-color: #31363a; + border-color: #2e3236; + box-shadow: 0 0 0 0.25rem rgba(88, 92, 96, 0.5); +} +.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #2e3236; + border-color: #2c2f33; +} +.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(88, 92, 96, 0.5); +} +.btn-primary:disabled, .btn-primary.disabled { + color: #fff; + background-color: #3a3f44; + border-color: #3a3f44; +} .btn-secondary { color: #fff; background-color: #7a8288; - border-color: #7a8288; } - .btn-secondary:hover { - color: #fff; - background-color: #686f74; - border-color: #62686d; } - .btn-check:focus + .btn-secondary, .btn-secondary:focus { - color: #fff; - background-color: #686f74; - border-color: #62686d; - box-shadow: 0 0 0 0.25rem rgba(142, 149, 154, 0.5); } - .btn-check:checked + .btn-secondary, - .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, - .show > .btn-secondary.dropdown-toggle { - color: #fff; - background-color: #62686d; - border-color: #5c6266; } - .btn-check:checked + .btn-secondary:focus, - .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, - .show > .btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(142, 149, 154, 0.5); } - .btn-secondary:disabled, .btn-secondary.disabled { - color: #fff; - background-color: #7a8288; - border-color: #7a8288; } + border-color: #7a8288; +} +.btn-secondary:hover { + color: #fff; + background-color: #686f74; + border-color: #62686d; +} +.btn-check:focus + .btn-secondary, .btn-secondary:focus { + color: #fff; + background-color: #686f74; + border-color: #62686d; + box-shadow: 0 0 0 0.25rem rgba(142, 149, 154, 0.5); +} +.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #62686d; + border-color: #5c6266; +} +.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(142, 149, 154, 0.5); +} +.btn-secondary:disabled, .btn-secondary.disabled { + color: #fff; + background-color: #7a8288; + border-color: #7a8288; +} .btn-success { color: #fff; background-color: #62c462; - border-color: #62c462; } - .btn-success:hover { - color: #fff; - background-color: #53a753; - border-color: #4e9d4e; } - .btn-check:focus + .btn-success, .btn-success:focus { - color: #fff; - background-color: #53a753; - border-color: #4e9d4e; - box-shadow: 0 0 0 0.25rem rgba(122, 205, 122, 0.5); } - .btn-check:checked + .btn-success, - .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, - .show > .btn-success.dropdown-toggle { - color: #fff; - background-color: #4e9d4e; - border-color: #4a934a; } - .btn-check:checked + .btn-success:focus, - .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, - .show > .btn-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(122, 205, 122, 0.5); } - .btn-success:disabled, .btn-success.disabled { - color: #fff; - background-color: #62c462; - border-color: #62c462; } + border-color: #62c462; +} +.btn-success:hover { + color: #fff; + background-color: #53a753; + border-color: #4e9d4e; +} +.btn-check:focus + .btn-success, .btn-success:focus { + color: #fff; + background-color: #53a753; + border-color: #4e9d4e; + box-shadow: 0 0 0 0.25rem rgba(122, 205, 122, 0.5); +} +.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #4e9d4e; + border-color: #4a934a; +} +.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(122, 205, 122, 0.5); +} +.btn-success:disabled, .btn-success.disabled { + color: #fff; + background-color: #62c462; + border-color: #62c462; +} .btn-info { color: #fff; background-color: #5bc0de; - border-color: #5bc0de; } - .btn-info:hover { - color: #fff; - background-color: #4da3bd; - border-color: #499ab2; } - .btn-check:focus + .btn-info, .btn-info:focus { - color: #fff; - background-color: #4da3bd; - border-color: #499ab2; - box-shadow: 0 0 0 0.25rem rgba(116, 201, 227, 0.5); } - .btn-check:checked + .btn-info, - .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, - .show > .btn-info.dropdown-toggle { - color: #fff; - background-color: #499ab2; - border-color: #4490a7; } - .btn-check:checked + .btn-info:focus, - .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, - .show > .btn-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(116, 201, 227, 0.5); } - .btn-info:disabled, .btn-info.disabled { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; } + border-color: #5bc0de; +} +.btn-info:hover { + color: #fff; + background-color: #4da3bd; + border-color: #499ab2; +} +.btn-check:focus + .btn-info, .btn-info:focus { + color: #fff; + background-color: #4da3bd; + border-color: #499ab2; + box-shadow: 0 0 0 0.25rem rgba(116, 201, 227, 0.5); +} +.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #499ab2; + border-color: #4490a7; +} +.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(116, 201, 227, 0.5); +} +.btn-info:disabled, .btn-info.disabled { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; +} .btn-warning { color: #fff; background-color: #f89406; - border-color: #f89406; } - .btn-warning:hover { - color: #fff; - background-color: #d37e05; - border-color: #c67605; } - .btn-check:focus + .btn-warning, .btn-warning:focus { - color: #fff; - background-color: #d37e05; - border-color: #c67605; - box-shadow: 0 0 0 0.25rem rgba(249, 164, 43, 0.5); } - .btn-check:checked + .btn-warning, - .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, - .show > .btn-warning.dropdown-toggle { - color: #fff; - background-color: #c67605; - border-color: #ba6f05; } - .btn-check:checked + .btn-warning:focus, - .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, - .show > .btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(249, 164, 43, 0.5); } - .btn-warning:disabled, .btn-warning.disabled { - color: #fff; - background-color: #f89406; - border-color: #f89406; } + border-color: #f89406; +} +.btn-warning:hover { + color: #fff; + background-color: #d37e05; + border-color: #c67605; +} +.btn-check:focus + .btn-warning, .btn-warning:focus { + color: #fff; + background-color: #d37e05; + border-color: #c67605; + box-shadow: 0 0 0 0.25rem rgba(249, 164, 43, 0.5); +} +.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #c67605; + border-color: #ba6f05; +} +.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(249, 164, 43, 0.5); +} +.btn-warning:disabled, .btn-warning.disabled { + color: #fff; + background-color: #f89406; + border-color: #f89406; +} .btn-danger { color: #fff; background-color: #ee5f5b; - border-color: #ee5f5b; } - .btn-danger:hover { - color: #fff; - background-color: #ca514d; - border-color: #be4c49; } - .btn-check:focus + .btn-danger, .btn-danger:focus { - color: #fff; - background-color: #ca514d; - border-color: #be4c49; - box-shadow: 0 0 0 0.25rem rgba(241, 119, 116, 0.5); } - .btn-check:checked + .btn-danger, - .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, - .show > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #be4c49; - border-color: #b34744; } - .btn-check:checked + .btn-danger:focus, - .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, - .show > .btn-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(241, 119, 116, 0.5); } - .btn-danger:disabled, .btn-danger.disabled { - color: #fff; - background-color: #ee5f5b; - border-color: #ee5f5b; } + border-color: #ee5f5b; +} +.btn-danger:hover { + color: #fff; + background-color: #ca514d; + border-color: #be4c49; +} +.btn-check:focus + .btn-danger, .btn-danger:focus { + color: #fff; + background-color: #ca514d; + border-color: #be4c49; + box-shadow: 0 0 0 0.25rem rgba(241, 119, 116, 0.5); +} +.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #be4c49; + border-color: #b34744; +} +.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(241, 119, 116, 0.5); +} +.btn-danger:disabled, .btn-danger.disabled { + color: #fff; + background-color: #ee5f5b; + border-color: #ee5f5b; +} .btn-light { color: #000; background-color: #e9ecef; - border-color: #e9ecef; } - .btn-light:hover { - color: #000; - background-color: #eceff1; - border-color: #ebeef1; } - .btn-check:focus + .btn-light, .btn-light:focus { - color: #000; - background-color: #eceff1; - border-color: #ebeef1; - box-shadow: 0 0 0 0.25rem rgba(198, 201, 203, 0.5); } - .btn-check:checked + .btn-light, - .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, - .show > .btn-light.dropdown-toggle { - color: #000; - background-color: #edf0f2; - border-color: #ebeef1; } - .btn-check:checked + .btn-light:focus, - .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, - .show > .btn-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(198, 201, 203, 0.5); } - .btn-light:disabled, .btn-light.disabled { - color: #000; - background-color: #e9ecef; - border-color: #e9ecef; } + border-color: #e9ecef; +} +.btn-light:hover { + color: #000; + background-color: #eceff1; + border-color: #ebeef1; +} +.btn-check:focus + .btn-light, .btn-light:focus { + color: #000; + background-color: #eceff1; + border-color: #ebeef1; + box-shadow: 0 0 0 0.25rem rgba(198, 201, 203, 0.5); +} +.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle { + color: #000; + background-color: #edf0f2; + border-color: #ebeef1; +} +.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(198, 201, 203, 0.5); +} +.btn-light:disabled, .btn-light.disabled { + color: #000; + background-color: #e9ecef; + border-color: #e9ecef; +} .btn-dark { color: #fff; background-color: #272b30; - border-color: #272b30; } - .btn-dark:hover { - color: #fff; - background-color: #212529; - border-color: #1f2226; } - .btn-check:focus + .btn-dark, .btn-dark:focus { - color: #fff; - background-color: #212529; - border-color: #1f2226; - box-shadow: 0 0 0 0.25rem rgba(71, 75, 79, 0.5); } - .btn-check:checked + .btn-dark, - .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, - .show > .btn-dark.dropdown-toggle { - color: #fff; - background-color: #1f2226; - border-color: #1d2024; } - .btn-check:checked + .btn-dark:focus, - .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, - .show > .btn-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(71, 75, 79, 0.5); } - .btn-dark:disabled, .btn-dark.disabled { - color: #fff; - background-color: #272b30; - border-color: #272b30; } + border-color: #272b30; +} +.btn-dark:hover { + color: #fff; + background-color: #212529; + border-color: #1f2226; +} +.btn-check:focus + .btn-dark, .btn-dark:focus { + color: #fff; + background-color: #212529; + border-color: #1f2226; + box-shadow: 0 0 0 0.25rem rgba(71, 75, 79, 0.5); +} +.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1f2226; + border-color: #1d2024; +} +.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(71, 75, 79, 0.5); +} +.btn-dark:disabled, .btn-dark.disabled { + color: #fff; + background-color: #272b30; + border-color: #272b30; +} .btn-outline-primary { color: #3a3f44; - border-color: #3a3f44; } - .btn-outline-primary:hover { - color: #fff; - background-color: #3a3f44; - border-color: #3a3f44; } - .btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { - box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.5); } - .btn-check:checked + .btn-outline-primary, - .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { - color: #fff; - background-color: #3a3f44; - border-color: #3a3f44; } - .btn-check:checked + .btn-outline-primary:focus, - .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.5); } - .btn-outline-primary:disabled, .btn-outline-primary.disabled { - color: #3a3f44; - background-color: transparent; } + border-color: #3a3f44; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #3a3f44; + border-color: #3a3f44; +} +.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { + box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.5); +} +.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { + color: #fff; + background-color: #3a3f44; + border-color: #3a3f44; +} +.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.5); +} +.btn-outline-primary:disabled, .btn-outline-primary.disabled { + color: #3a3f44; + background-color: transparent; +} .btn-outline-secondary { color: #7a8288; - border-color: #7a8288; } - .btn-outline-secondary:hover { - color: #fff; - background-color: #7a8288; - border-color: #7a8288; } - .btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { - box-shadow: 0 0 0 0.25rem rgba(122, 130, 136, 0.5); } - .btn-check:checked + .btn-outline-secondary, - .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { - color: #fff; - background-color: #7a8288; - border-color: #7a8288; } - .btn-check:checked + .btn-outline-secondary:focus, - .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(122, 130, 136, 0.5); } - .btn-outline-secondary:disabled, .btn-outline-secondary.disabled { - color: #7a8288; - background-color: transparent; } + border-color: #7a8288; +} +.btn-outline-secondary:hover { + color: #fff; + background-color: #7a8288; + border-color: #7a8288; +} +.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { + box-shadow: 0 0 0 0.25rem rgba(122, 130, 136, 0.5); +} +.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { + color: #fff; + background-color: #7a8288; + border-color: #7a8288; +} +.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(122, 130, 136, 0.5); +} +.btn-outline-secondary:disabled, .btn-outline-secondary.disabled { + color: #7a8288; + background-color: transparent; +} .btn-outline-success { color: #62c462; - border-color: #62c462; } - .btn-outline-success:hover { - color: #fff; - background-color: #62c462; - border-color: #62c462; } - .btn-check:focus + .btn-outline-success, .btn-outline-success:focus { - box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.5); } - .btn-check:checked + .btn-outline-success, - .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { - color: #fff; - background-color: #62c462; - border-color: #62c462; } - .btn-check:checked + .btn-outline-success:focus, - .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.5); } - .btn-outline-success:disabled, .btn-outline-success.disabled { - color: #62c462; - background-color: transparent; } + border-color: #62c462; +} +.btn-outline-success:hover { + color: #fff; + background-color: #62c462; + border-color: #62c462; +} +.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { + box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.5); +} +.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { + color: #fff; + background-color: #62c462; + border-color: #62c462; +} +.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.5); +} +.btn-outline-success:disabled, .btn-outline-success.disabled { + color: #62c462; + background-color: transparent; +} .btn-outline-info { color: #5bc0de; - border-color: #5bc0de; } - .btn-outline-info:hover { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; } - .btn-check:focus + .btn-outline-info, .btn-outline-info:focus { - box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.5); } - .btn-check:checked + .btn-outline-info, - .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; } - .btn-check:checked + .btn-outline-info:focus, - .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.5); } - .btn-outline-info:disabled, .btn-outline-info.disabled { - color: #5bc0de; - background-color: transparent; } + border-color: #5bc0de; +} +.btn-outline-info:hover { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { + box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.5); +} +.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.5); +} +.btn-outline-info:disabled, .btn-outline-info.disabled { + color: #5bc0de; + background-color: transparent; +} .btn-outline-warning { color: #f89406; - border-color: #f89406; } - .btn-outline-warning:hover { - color: #fff; - background-color: #f89406; - border-color: #f89406; } - .btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.5); } - .btn-check:checked + .btn-outline-warning, - .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { - color: #fff; - background-color: #f89406; - border-color: #f89406; } - .btn-check:checked + .btn-outline-warning:focus, - .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.5); } - .btn-outline-warning:disabled, .btn-outline-warning.disabled { - color: #f89406; - background-color: transparent; } + border-color: #f89406; +} +.btn-outline-warning:hover { + color: #fff; + background-color: #f89406; + border-color: #f89406; +} +.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.5); +} +.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { + color: #fff; + background-color: #f89406; + border-color: #f89406; +} +.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 148, 6, 0.5); +} +.btn-outline-warning:disabled, .btn-outline-warning.disabled { + color: #f89406; + background-color: transparent; +} .btn-outline-danger { color: #ee5f5b; - border-color: #ee5f5b; } - .btn-outline-danger:hover { - color: #fff; - background-color: #ee5f5b; - border-color: #ee5f5b; } - .btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { - box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.5); } - .btn-check:checked + .btn-outline-danger, - .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { - color: #fff; - background-color: #ee5f5b; - border-color: #ee5f5b; } - .btn-check:checked + .btn-outline-danger:focus, - .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.5); } - .btn-outline-danger:disabled, .btn-outline-danger.disabled { - color: #ee5f5b; - background-color: transparent; } + border-color: #ee5f5b; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #ee5f5b; + border-color: #ee5f5b; +} +.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { + box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.5); +} +.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { + color: #fff; + background-color: #ee5f5b; + border-color: #ee5f5b; +} +.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.5); +} +.btn-outline-danger:disabled, .btn-outline-danger.disabled { + color: #ee5f5b; + background-color: transparent; +} .btn-outline-light { color: #e9ecef; - border-color: #e9ecef; } - .btn-outline-light:hover { - color: #000; - background-color: #e9ecef; - border-color: #e9ecef; } - .btn-check:focus + .btn-outline-light, .btn-outline-light:focus { - box-shadow: 0 0 0 0.25rem rgba(233, 236, 239, 0.5); } - .btn-check:checked + .btn-outline-light, - .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { - color: #000; - background-color: #e9ecef; - border-color: #e9ecef; } - .btn-check:checked + .btn-outline-light:focus, - .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(233, 236, 239, 0.5); } - .btn-outline-light:disabled, .btn-outline-light.disabled { - color: #e9ecef; - background-color: transparent; } + border-color: #e9ecef; +} +.btn-outline-light:hover { + color: #000; + background-color: #e9ecef; + border-color: #e9ecef; +} +.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { + box-shadow: 0 0 0 0.25rem rgba(233, 236, 239, 0.5); +} +.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { + color: #000; + background-color: #e9ecef; + border-color: #e9ecef; +} +.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(233, 236, 239, 0.5); +} +.btn-outline-light:disabled, .btn-outline-light.disabled { + color: #e9ecef; + background-color: transparent; +} .btn-outline-dark { color: #272b30; - border-color: #272b30; } - .btn-outline-dark:hover { - color: #fff; - background-color: #272b30; - border-color: #272b30; } - .btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { - box-shadow: 0 0 0 0.25rem rgba(39, 43, 48, 0.5); } - .btn-check:checked + .btn-outline-dark, - .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { - color: #fff; - background-color: #272b30; - border-color: #272b30; } - .btn-check:checked + .btn-outline-dark:focus, - .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(39, 43, 48, 0.5); } - .btn-outline-dark:disabled, .btn-outline-dark.disabled { - color: #272b30; - background-color: transparent; } + border-color: #272b30; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #272b30; + border-color: #272b30; +} +.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { + box-shadow: 0 0 0 0.25rem rgba(39, 43, 48, 0.5); +} +.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { + color: #fff; + background-color: #272b30; + border-color: #272b30; +} +.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(39, 43, 48, 0.5); +} +.btn-outline-dark:disabled, .btn-outline-dark.disabled { + color: #272b30; + background-color: transparent; +} .btn-link { font-weight: 400; color: #fff; - text-decoration: underline; } - .btn-link:hover { - color: #cccccc; } - .btn-link:disabled, .btn-link.disabled { - color: #7a8288; } + text-decoration: underline; +} +.btn-link:hover { + color: #cccccc; +} +.btn-link:disabled, .btn-link.disabled { + color: #7a8288; +} .btn-lg { padding: 0.5rem 1rem; font-size: 1.25rem; - border-radius: 0.3rem; } + border-radius: 0.3rem; +} .btn-sm { padding: 0.25rem 0.5rem; font-size: 0.875rem; - border-radius: 0.2rem; } + border-radius: 0.2rem; +} .form-label { - margin-bottom: 0.5rem; } + margin-bottom: 0.5rem; +} .col-form-label { padding-top: calc(0.375rem + 1px); padding-bottom: calc(0.375rem + 1px); margin-bottom: 0; font-size: inherit; - line-height: 1.5; } + line-height: 1.5; +} .col-form-label-lg { padding-top: calc(0.5rem + 1px); padding-bottom: calc(0.5rem + 1px); - font-size: 1.25rem; } + font-size: 1.25rem; +} .col-form-label-sm { padding-top: calc(0.25rem + 1px); padding-bottom: calc(0.25rem + 1px); - font-size: 0.875rem; } + font-size: 0.875rem; +} .form-text { margin-top: 0.25rem; font-size: 0.875em; - color: #7a8288; } + color: #7a8288; +} .form-control { display: block; @@ -849,64 +1118,81 @@ ul.sidebar-elements li > a.sidebar-link.active::after { border: 1px solid #ced4da; appearance: none; border-radius: 0.25rem; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .form-control { - transition: none; } } - .form-control[type="file"] { - overflow: hidden; } - .form-control[type="file"]:not(:disabled):not([readonly]) { - cursor: pointer; } - .form-control:focus { - color: #272b30; - background-color: #fff; - border-color: #9d9fa2; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); } - .form-control::-webkit-date-and-time-value { - height: 1.5em; } - .form-control::placeholder { - color: #7a8288; - opacity: 1; } - .form-control:disabled, .form-control[readonly] { - background-color: #ccc; - opacity: 1; } + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none; + } +} +.form-control[type=file] { + overflow: hidden; +} +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control:focus { + color: #272b30; + background-color: #fff; + border-color: #9d9fa2; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); +} +.form-control::-webkit-date-and-time-value { + height: 1.5em; +} +.form-control::placeholder { + color: #7a8288; + opacity: 1; +} +.form-control:disabled, .form-control[readonly] { + background-color: #ccc; + opacity: 1; +} +.form-control::file-selector-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + margin-inline-end: 0.75rem; + color: #272b30; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { .form-control::file-selector-button { - padding: 0.375rem 0.75rem; - margin: -0.375rem -0.75rem; - margin-inline-end: 0.75rem; - color: #272b30; - background-color: #e9ecef; - pointer-events: none; - border-color: inherit; - border-style: solid; - border-width: 0; - border-inline-end-width: 1px; - border-radius: 0; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .form-control::file-selector-button { - transition: none; } } - .form-control:hover:not(:disabled):not([readonly])::file-selector-button { - background-color: #dde0e3; } + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #dde0e3; +} +.form-control::-webkit-file-upload-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + margin-inline-end: 0.75rem; + color: #272b30; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { .form-control::-webkit-file-upload-button { - padding: 0.375rem 0.75rem; - margin: -0.375rem -0.75rem; - margin-inline-end: 0.75rem; - color: #272b30; - background-color: #e9ecef; - pointer-events: none; - border-color: inherit; - border-style: solid; - border-width: 0; - border-inline-end-width: 1px; - border-radius: 0; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .form-control::-webkit-file-upload-button { - transition: none; } } - .form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { - background-color: #dde0e3; } + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3; +} .form-control-plaintext { display: block; @@ -917,60 +1203,73 @@ ul.sidebar-elements li > a.sidebar-link.active::after { color: #aaa; background-color: transparent; border: solid transparent; - border-width: 1px 0; } - .form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { - padding-right: 0; - padding-left: 0; } + border-width: 1px 0; +} +.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { + padding-right: 0; + padding-left: 0; +} .form-control-sm { min-height: calc(1.5em + 0.5rem + 2px); padding: 0.25rem 0.5rem; font-size: 0.875rem; - border-radius: 0.2rem; } - .form-control-sm::file-selector-button { - padding: 0.25rem 0.5rem; - margin: -0.25rem -0.5rem; - margin-inline-end: 0.5rem; } - .form-control-sm::-webkit-file-upload-button { - padding: 0.25rem 0.5rem; - margin: -0.25rem -0.5rem; - margin-inline-end: 0.5rem; } + border-radius: 0.2rem; +} +.form-control-sm::file-selector-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + margin-inline-end: 0.5rem; +} +.form-control-sm::-webkit-file-upload-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + margin-inline-end: 0.5rem; +} .form-control-lg { min-height: calc(1.5em + 1rem + 2px); padding: 0.5rem 1rem; font-size: 1.25rem; - border-radius: 0.3rem; } - .form-control-lg::file-selector-button { - padding: 0.5rem 1rem; - margin: -0.5rem -1rem; - margin-inline-end: 1rem; } - .form-control-lg::-webkit-file-upload-button { - padding: 0.5rem 1rem; - margin: -0.5rem -1rem; - margin-inline-end: 1rem; } + border-radius: 0.3rem; +} +.form-control-lg::file-selector-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + margin-inline-end: 1rem; +} +.form-control-lg::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + margin-inline-end: 1rem; +} textarea.form-control { - min-height: calc(1.5em + 0.75rem + 2px); } - + min-height: calc(1.5em + 0.75rem + 2px); +} textarea.form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); } - + min-height: calc(1.5em + 0.5rem + 2px); +} textarea.form-control-lg { - min-height: calc(1.5em + 1rem + 2px); } + min-height: calc(1.5em + 1rem + 2px); +} .form-control-color { width: 3rem; height: auto; - padding: 0.375rem; } - .form-control-color:not(:disabled):not([readonly]) { - cursor: pointer; } - .form-control-color::-moz-color-swatch { - height: 1.5em; - border-radius: 0.25rem; } - .form-control-color::-webkit-color-swatch { - height: 1.5em; - border-radius: 0.25rem; } + padding: 0.375rem; +} +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control-color::-moz-color-swatch { + height: 1.5em; + border-radius: 0.25rem; +} +.form-control-color::-webkit-color-swatch { + height: 1.5em; + border-radius: 0.25rem; +} .form-select { display: block; @@ -989,43 +1288,56 @@ textarea.form-control-lg { border: 1px solid #ced4da; border-radius: 0.25rem; transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - appearance: none; } - @media (prefers-reduced-motion: reduce) { - .form-select { - transition: none; } } - .form-select:focus { - border-color: #9d9fa2; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); } - .form-select[multiple], .form-select[size]:not([size="1"]) { - padding-right: 0.75rem; - background-image: none; } - .form-select:disabled { - background-color: #e9ecef; } - .form-select:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #272b30; } + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-select { + transition: none; + } +} +.form-select:focus { + border-color: #9d9fa2; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); +} +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: 0.75rem; + background-image: none; +} +.form-select:disabled { + background-color: #e9ecef; +} +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #272b30; +} .form-select-sm { padding-top: 0.25rem; padding-bottom: 0.25rem; padding-left: 0.5rem; - font-size: 0.875rem; } + font-size: 0.875rem; + border-radius: 0.2rem; +} .form-select-lg { padding-top: 0.5rem; padding-bottom: 0.5rem; padding-left: 1rem; - font-size: 1.25rem; } + font-size: 1.25rem; + border-radius: 0.3rem; +} .form-check { display: block; min-height: 1.5rem; padding-left: 1.5em; - margin-bottom: 0.125rem; } - .form-check .form-check-input { - float: left; - margin-left: -1.5em; } + margin-bottom: 0.125rem; +} +.form-check .form-check-input { + float: left; + margin-left: -1.5em; +} .form-check-input { width: 1em; @@ -1038,191 +1350,246 @@ textarea.form-control-lg { background-size: contain; border: 1px solid rgba(0, 0, 0, 0.25); appearance: none; - color-adjust: exact; } - .form-check-input[type="checkbox"] { - border-radius: 0.25em; } - .form-check-input[type="radio"] { - border-radius: 50%; } - .form-check-input:active { - filter: brightness(90%); } - .form-check-input:focus { - border-color: #9d9fa2; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); } - .form-check-input:checked { - background-color: #3a3f44; - border-color: #3a3f44; } - .form-check-input:checked[type="checkbox"] { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"); } - .form-check-input:checked[type="radio"] { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); } - .form-check-input[type="checkbox"]:indeterminate { - background-color: #3a3f44; - border-color: #3a3f44; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); } - .form-check-input:disabled { - pointer-events: none; - filter: none; - opacity: 0.5; } - .form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { - opacity: 0.5; } + color-adjust: exact; +} +.form-check-input[type=checkbox] { + border-radius: 0.25em; +} +.form-check-input[type=radio] { + border-radius: 50%; +} +.form-check-input:active { + filter: brightness(90%); +} +.form-check-input:focus { + border-color: #9d9fa2; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(58, 63, 68, 0.25); +} +.form-check-input:checked { + background-color: #3a3f44; + border-color: #3a3f44; +} +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"); +} +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); +} +.form-check-input[type=checkbox]:indeterminate { + background-color: #3a3f44; + border-color: #3a3f44; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); +} +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: 0.5; +} +.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { + opacity: 0.5; +} .form-switch { - padding-left: 2.5em; } + padding-left: 2.5em; +} +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { .form-switch .form-check-input { - width: 2em; - margin-left: -2.5em; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); - background-position: left center; - border-radius: 2em; - transition: background-position 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .form-switch .form-check-input { - transition: none; } } - .form-switch .form-check-input:focus { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239d9fa2'/%3e%3c/svg%3e"); } - .form-switch .form-check-input:checked { - background-position: right center; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); } + transition: none; + } +} +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239d9fa2'/%3e%3c/svg%3e"); +} +.form-switch .form-check-input:checked { + background-position: right center; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); +} .form-check-inline { display: inline-block; - margin-right: 1rem; } + margin-right: 1rem; +} .btn-check { position: absolute; clip: rect(0, 0, 0, 0); - pointer-events: none; } - .btn-check[disabled] + .btn, .btn-check:disabled + .btn { - pointer-events: none; - filter: none; - opacity: 0.65; } + pointer-events: none; +} +.btn-check[disabled] + .btn, .btn-check:disabled + .btn { + pointer-events: none; + filter: none; + opacity: 0.65; +} .form-range { width: 100%; height: 1.5rem; padding: 0; background-color: transparent; - appearance: none; } - .form-range:focus { - outline: 0; } - .form-range:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #272b30, 0 0 0 0.25rem rgba(58, 63, 68, 0.25); } - .form-range:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #272b30, 0 0 0 0.25rem rgba(58, 63, 68, 0.25); } - .form-range::-moz-focus-outer { - border: 0; } + appearance: none; +} +.form-range:focus { + outline: 0; +} +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #272b30, 0 0 0 0.25rem rgba(58, 63, 68, 0.25); +} +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #272b30, 0 0 0 0.25rem rgba(58, 63, 68, 0.25); +} +.form-range::-moz-focus-outer { + border: 0; +} +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -0.25rem; + background-color: #3a3f44; + border: 0; + border-radius: 1rem; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { .form-range::-webkit-slider-thumb { - width: 1rem; - height: 1rem; - margin-top: -0.25rem; - background-color: #3a3f44; - border: 0; - border-radius: 1rem; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - appearance: none; } - @media (prefers-reduced-motion: reduce) { - .form-range::-webkit-slider-thumb { - transition: none; } } - .form-range::-webkit-slider-thumb:active { - background-color: #c4c5c7; } - .form-range::-webkit-slider-runnable-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; } + transition: none; + } +} +.form-range::-webkit-slider-thumb:active { + background-color: #c4c5c7; +} +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #3a3f44; + border: 0; + border-radius: 1rem; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { .form-range::-moz-range-thumb { - width: 1rem; - height: 1rem; - background-color: #3a3f44; - border: 0; - border-radius: 1rem; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - appearance: none; } - @media (prefers-reduced-motion: reduce) { - .form-range::-moz-range-thumb { - transition: none; } } - .form-range::-moz-range-thumb:active { - background-color: #c4c5c7; } - .form-range::-moz-range-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; } - .form-range:disabled { - pointer-events: none; } - .form-range:disabled::-webkit-slider-thumb { - background-color: #999; } - .form-range:disabled::-moz-range-thumb { - background-color: #999; } + transition: none; + } +} +.form-range::-moz-range-thumb:active { + background-color: #c4c5c7; +} +.form-range::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range:disabled { + pointer-events: none; +} +.form-range:disabled::-webkit-slider-thumb { + background-color: #999; +} +.form-range:disabled::-moz-range-thumb { + background-color: #999; +} .form-floating { - position: relative; } - .form-floating > .form-control, - .form-floating > .form-select { - height: calc(3.5rem + 2px); - line-height: 1.25; } + position: relative; +} +.form-floating > .form-control, +.form-floating > .form-select { + height: calc(3.5rem + 2px); + line-height: 1.25; +} +.form-floating > label { + position: absolute; + top: 0; + left: 0; + height: 100%; + padding: 1rem 0.75rem; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { .form-floating > label { - position: absolute; - top: 0; - left: 0; - height: 100%; - padding: 1rem 0.75rem; - pointer-events: none; - border: 1px solid transparent; - transform-origin: 0 0; - transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .form-floating > label { - transition: none; } } - .form-floating > .form-control { - padding: 1rem 0.75rem; } - .form-floating > .form-control::placeholder { - color: transparent; } - .form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { - padding-top: 1.625rem; - padding-bottom: 0.625rem; } - .form-floating > .form-control:-webkit-autofill { - padding-top: 1.625rem; - padding-bottom: 0.625rem; } - .form-floating > .form-select { - padding-top: 1.625rem; - padding-bottom: 0.625rem; } - .form-floating > .form-control:focus ~ label, - .form-floating > .form-control:not(:placeholder-shown) ~ label, - .form-floating > .form-select ~ label { - opacity: 0.65; - transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); } - .form-floating > .form-control:-webkit-autofill ~ label { - opacity: 0.65; - transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); } + transition: none; + } +} +.form-floating > .form-control { + padding: 1rem 0.75rem; +} +.form-floating > .form-control::placeholder { + color: transparent; +} +.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:focus ~ label, +.form-floating > .form-control:not(:placeholder-shown) ~ label, +.form-floating > .form-select ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:-webkit-autofill ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} .input-group { position: relative; display: flex; flex-wrap: wrap; align-items: stretch; - width: 100%; } - .input-group > .form-control, - .input-group > .form-select { - position: relative; - flex: 1 1 auto; - width: 1%; - min-width: 0; } - .input-group > .form-control:focus, - .input-group > .form-select:focus { - z-index: 3; } - .input-group .btn { - position: relative; - z-index: 2; } - .input-group .btn:focus { - z-index: 3; } + width: 100%; +} +.input-group > .form-control, +.input-group > .form-select { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0; +} +.input-group > .form-control:focus, +.input-group > .form-select:focus { + z-index: 3; +} +.input-group .btn { + position: relative; + z-index: 2; +} +.input-group .btn:focus { + z-index: 3; +} .input-group-text { display: flex; @@ -1236,7 +1603,8 @@ textarea.form-control-lg { white-space: nowrap; background-color: #e9ecef; border: 1px solid #ced4da; - border-radius: 0.25rem; } + border-radius: 0.25rem; +} .input-group-lg > .form-control, .input-group-lg > .form-select, @@ -1244,7 +1612,8 @@ textarea.form-control-lg { .input-group-lg > .btn { padding: 0.5rem 1rem; font-size: 1.25rem; - border-radius: 0.3rem; } + border-radius: 0.3rem; +} .input-group-sm > .form-control, .input-group-sm > .form-select, @@ -1252,33 +1621,37 @@ textarea.form-control-lg { .input-group-sm > .btn { padding: 0.25rem 0.5rem; font-size: 0.875rem; - border-radius: 0.2rem; } + border-radius: 0.2rem; +} .input-group-lg > .form-select, .input-group-sm > .form-select { - padding-right: 3rem; } + padding-right: 3rem; +} .input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu), -.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n + 3) { +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) { border-top-right-radius: 0; - border-bottom-right-radius: 0; } - -.input-group.has-validation > :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu), -.input-group.has-validation > .dropdown-toggle:nth-last-child(n + 4) { + border-bottom-right-radius: 0; +} +.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu), +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4) { border-top-right-radius: 0; - border-bottom-right-radius: 0; } - + border-bottom-right-radius: 0; +} .input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { margin-left: -1px; border-top-left-radius: 0; - border-bottom-left-radius: 0; } + border-bottom-left-radius: 0; +} .valid-feedback { display: none; width: 100%; margin-top: 0.25rem; font-size: 0.875em; - color: #62c462; } + color: #62c462; +} .valid-tooltip { position: absolute; @@ -1287,17 +1660,19 @@ textarea.form-control-lg { display: none; max-width: 100%; padding: 0.25rem 0.5rem; - margin-top: .1rem; + margin-top: 0.1rem; font-size: 0.875rem; color: #fff; background-color: rgba(98, 196, 98, 0.9); - border-radius: 0.25rem; } + border-radius: 0.25rem; +} .was-validated :valid ~ .valid-feedback, .was-validated :valid ~ .valid-tooltip, .is-valid ~ .valid-feedback, .is-valid ~ .valid-tooltip { - display: block; } + display: block; +} .was-validated .form-control:valid, .form-control.is-valid { border-color: #62c462; @@ -1305,53 +1680,67 @@ textarea.form-control-lg { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2362c462' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .was-validated .form-control:valid:focus, .form-control.is-valid:focus { - border-color: #62c462; - box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:valid:focus, .form-control.is-valid:focus { + border-color: #62c462; + box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.25); +} .was-validated textarea.form-control:valid, textarea.form-control.is-valid { padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); } + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} .was-validated .form-select:valid, .form-select.is-valid { - border-color: #62c462; } - .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { - padding-right: 4.125rem; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%233a3f44' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2362c462' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-position: right 0.75rem center, center right 2.25rem; - background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .was-validated .form-select:valid:focus, .form-select.is-valid:focus { - border-color: #62c462; - box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.25); } + border-color: #62c462; +} +.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%233a3f44' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2362c462' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:valid:focus, .form-select.is-valid:focus { + border-color: #62c462; + box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.25); +} .was-validated .form-check-input:valid, .form-check-input.is-valid { - border-color: #62c462; } - .was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { - background-color: #62c462; } - .was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { - box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.25); } - .was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { - color: #62c462; } + border-color: #62c462; +} +.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { + background-color: #62c462; +} +.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { + box-shadow: 0 0 0 0.25rem rgba(98, 196, 98, 0.25); +} +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #62c462; +} .form-check-inline .form-check-input ~ .valid-feedback { - margin-left: .5em; } + margin-left: 0.5em; +} -.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid, .was-validated -.input-group .form-select:valid, +.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid, +.was-validated .input-group .form-select:valid, .input-group .form-select.is-valid { - z-index: 1; } - .was-validated .input-group .form-control:valid:focus, .input-group .form-control.is-valid:focus, .was-validated - .input-group .form-select:valid:focus, - .input-group .form-select.is-valid:focus { - z-index: 3; } + z-index: 1; +} +.was-validated .input-group .form-control:valid:focus, .input-group .form-control.is-valid:focus, +.was-validated .input-group .form-select:valid:focus, +.input-group .form-select.is-valid:focus { + z-index: 3; +} .invalid-feedback { display: none; width: 100%; margin-top: 0.25rem; font-size: 0.875em; - color: #ee5f5b; } + color: #ee5f5b; +} .invalid-tooltip { position: absolute; @@ -1360,17 +1749,19 @@ textarea.form-control-lg { display: none; max-width: 100%; padding: 0.25rem 0.5rem; - margin-top: .1rem; + margin-top: 0.1rem; font-size: 0.875rem; color: #fff; background-color: rgba(238, 95, 91, 0.9); - border-radius: 0.25rem; } + border-radius: 0.25rem; +} .was-validated :invalid ~ .invalid-feedback, .was-validated :invalid ~ .invalid-tooltip, .is-invalid ~ .invalid-feedback, .is-invalid ~ .invalid-tooltip { - display: block; } + display: block; +} .was-validated .form-control:invalid, .form-control.is-invalid { border-color: #ee5f5b; @@ -1378,46 +1769,59 @@ textarea.form-control-lg { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ee5f5b'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ee5f5b' stroke='none'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { - border-color: #ee5f5b; - box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { + border-color: #ee5f5b; + box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.25); +} .was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); } + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} .was-validated .form-select:invalid, .form-select.is-invalid { - border-color: #ee5f5b; } - .was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] { - padding-right: 4.125rem; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%233a3f44' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ee5f5b'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ee5f5b' stroke='none'/%3e%3c/svg%3e"); - background-position: right 0.75rem center, center right 2.25rem; - background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .was-validated .form-select:invalid:focus, .form-select.is-invalid:focus { - border-color: #ee5f5b; - box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.25); } + border-color: #ee5f5b; +} +.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%233a3f44' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ee5f5b'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ee5f5b' stroke='none'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus { + border-color: #ee5f5b; + box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.25); +} .was-validated .form-check-input:invalid, .form-check-input.is-invalid { - border-color: #ee5f5b; } - .was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { - background-color: #ee5f5b; } - .was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { - box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.25); } - .was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { - color: #ee5f5b; } + border-color: #ee5f5b; +} +.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { + background-color: #ee5f5b; +} +.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { + box-shadow: 0 0 0 0.25rem rgba(238, 95, 91, 0.25); +} +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #ee5f5b; +} .form-check-inline .form-check-input ~ .invalid-feedback { - margin-left: .5em; } + margin-left: 0.5em; +} -.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid, .was-validated -.input-group .form-select:invalid, +.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid, +.was-validated .input-group .form-select:invalid, .input-group .form-select.is-invalid { - z-index: 2; } - .was-validated .input-group .form-control:invalid:focus, .input-group .form-control.is-invalid:focus, .was-validated - .input-group .form-select:invalid:focus, - .input-group .form-select.is-invalid:focus { - z-index: 3; } + z-index: 2; +} +.was-validated .input-group .form-control:invalid:focus, .input-group .form-control.is-invalid:focus, +.was-validated .input-group .form-select:invalid:focus, +.input-group .form-select.is-invalid:focus { + z-index: 3; +} .navbar { position: relative; @@ -1426,42 +1830,48 @@ textarea.form-control-lg { align-items: center; justify-content: space-between; padding-top: 0; - padding-bottom: 0; } - .navbar > .container, - .navbar > .container-fluid, .navbar > .container-sm, .navbar > .container-md, .navbar > .container-lg, .navbar > .container-xl, .navbar > .container-xxl { - display: flex; - flex-wrap: inherit; - align-items: center; - justify-content: space-between; } - + padding-bottom: 0; +} +.navbar > .container-xxl, .navbar > .container-xl, .navbar > .container-lg, .navbar > .container-md, .navbar > .container-sm, .navbar > .container, +.navbar > .container-fluid { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between; +} .navbar-brand { padding-top: 0.3125rem; padding-bottom: 0.3125rem; margin-right: 1rem; font-size: 1.25rem; text-decoration: none; - white-space: nowrap; } - + white-space: nowrap; +} .navbar-nav { display: flex; flex-direction: column; padding-left: 0; margin-bottom: 0; - list-style: none; } - .navbar-nav .nav-link { - padding-right: 0; - padding-left: 0; } - .navbar-nav .dropdown-menu { - position: static; } + list-style: none; +} +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} +.navbar-nav .dropdown-menu { + position: static; +} .navbar-text { padding-top: 0.5rem; - padding-bottom: 0.5rem; } + padding-bottom: 0.5rem; +} .navbar-collapse { flex-basis: 100%; flex-grow: 1; - align-items: center; } + align-items: center; +} .navbar-toggler { padding: 0.25rem 0.75rem; @@ -1470,16 +1880,21 @@ textarea.form-control-lg { background-color: transparent; border: 1px solid transparent; border-radius: 0.25rem; - transition: box-shadow 0.15s ease-in-out; } - @media (prefers-reduced-motion: reduce) { - .navbar-toggler { - transition: none; } } - .navbar-toggler:hover { - text-decoration: none; } - .navbar-toggler:focus { - text-decoration: none; - outline: 0; - box-shadow: 0 0 0 0.25rem; } + transition: box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none; + } +} +.navbar-toggler:hover { + text-decoration: none; +} +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 0.25rem; +} .navbar-toggler-icon { display: inline-block; @@ -1488,242 +1903,43 @@ textarea.form-control-lg { vertical-align: middle; background-repeat: no-repeat; background-position: center; - background-size: 100%; } + background-size: 100%; +} .navbar-nav-scroll { max-height: var(--bs-scroll-height, 75vh); - overflow-y: auto; } + overflow-y: auto; +} @media (min-width: 576px) { .navbar-expand-sm { flex-wrap: nowrap; - justify-content: flex-start; } - .navbar-expand-sm .navbar-nav { - flex-direction: row; } - .navbar-expand-sm .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-sm .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-sm .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-sm .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-sm .navbar-toggler { - display: none; } - .navbar-expand-sm .offcanvas-header { - display: none; } - .navbar-expand-sm .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; } - .navbar-expand-sm .offcanvas-top, - .navbar-expand-sm .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; } - .navbar-expand-sm .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; } } - -@media (min-width: 768px) { - .navbar-expand-md { - flex-wrap: nowrap; - justify-content: flex-start; } - .navbar-expand-md .navbar-nav { - flex-direction: row; } - .navbar-expand-md .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-md .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-md .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-md .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-md .navbar-toggler { - display: none; } - .navbar-expand-md .offcanvas-header { - display: none; } - .navbar-expand-md .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; } - .navbar-expand-md .offcanvas-top, - .navbar-expand-md .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; } - .navbar-expand-md .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; } } - -@media (min-width: 992px) { - .navbar-expand-lg { - flex-wrap: nowrap; - justify-content: flex-start; } - .navbar-expand-lg .navbar-nav { - flex-direction: row; } - .navbar-expand-lg .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-lg .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-lg .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-lg .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-lg .navbar-toggler { - display: none; } - .navbar-expand-lg .offcanvas-header { - display: none; } - .navbar-expand-lg .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; } - .navbar-expand-lg .offcanvas-top, - .navbar-expand-lg .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; } - .navbar-expand-lg .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; } } - -@media (min-width: 1200px) { - .navbar-expand-xl { - flex-wrap: nowrap; - justify-content: flex-start; } - .navbar-expand-xl .navbar-nav { - flex-direction: row; } - .navbar-expand-xl .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-xl .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-xl .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-xl .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-xl .navbar-toggler { - display: none; } - .navbar-expand-xl .offcanvas-header { - display: none; } - .navbar-expand-xl .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; } - .navbar-expand-xl .offcanvas-top, - .navbar-expand-xl .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; } - .navbar-expand-xl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; } } - -@media (min-width: 1400px) { - .navbar-expand-xxl { - flex-wrap: nowrap; - justify-content: flex-start; } - .navbar-expand-xxl .navbar-nav { - flex-direction: row; } - .navbar-expand-xxl .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand-xxl .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand-xxl .navbar-nav-scroll { - overflow: visible; } - .navbar-expand-xxl .navbar-collapse { - display: flex !important; - flex-basis: auto; } - .navbar-expand-xxl .navbar-toggler { - display: none; } - .navbar-expand-xxl .offcanvas-header { - display: none; } - .navbar-expand-xxl .offcanvas { - position: inherit; - bottom: 0; - z-index: 1000; - flex-grow: 1; - visibility: visible !important; - background-color: transparent; - border-right: 0; - border-left: 0; - transition: none; - transform: none; } - .navbar-expand-xxl .offcanvas-top, - .navbar-expand-xxl .offcanvas-bottom { - height: auto; - border-top: 0; - border-bottom: 0; } - .navbar-expand-xxl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; } } - -.navbar-expand { - flex-wrap: nowrap; - justify-content: flex-start; } - .navbar-expand .navbar-nav { - flex-direction: row; } - .navbar-expand .navbar-nav .dropdown-menu { - position: absolute; } - .navbar-expand .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; } - .navbar-expand .navbar-nav-scroll { - overflow: visible; } - .navbar-expand .navbar-collapse { + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-sm .navbar-collapse { display: flex !important; - flex-basis: auto; } - .navbar-expand .navbar-toggler { - display: none; } - .navbar-expand .offcanvas-header { - display: none; } - .navbar-expand .offcanvas { + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .offcanvas-header { + display: none; + } + .navbar-expand-sm .offcanvas { position: inherit; bottom: 0; z-index: 1000; @@ -1733,74 +1949,351 @@ textarea.form-control-lg { border-right: 0; border-left: 0; transition: none; - transform: none; } - .navbar-expand .offcanvas-top, - .navbar-expand .offcanvas-bottom { + transform: none; + } + .navbar-expand-sm .offcanvas-top, +.navbar-expand-sm .offcanvas-bottom { height: auto; border-top: 0; - border-bottom: 0; } - .navbar-expand .offcanvas-body { + border-bottom: 0; + } + .navbar-expand-sm .offcanvas-body { display: flex; flex-grow: 0; padding: 0; - overflow-y: visible; } + overflow-y: visible; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .offcanvas-header { + display: none; + } + .navbar-expand-md .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-md .offcanvas-top, +.navbar-expand-md .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .offcanvas-header { + display: none; + } + .navbar-expand-lg .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-lg .offcanvas-top, +.navbar-expand-lg .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .offcanvas-header { + display: none; + } + .navbar-expand-xl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-xl .offcanvas-top, +.navbar-expand-xl .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xxl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xxl .navbar-toggler { + display: none; + } + .navbar-expand-xxl .offcanvas-header { + display: none; + } + .navbar-expand-xxl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-xxl .offcanvas-top, +.navbar-expand-xxl .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start; +} +.navbar-expand .navbar-nav { + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} +.navbar-expand .navbar-nav-scroll { + overflow: visible; +} +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-expand .offcanvas-header { + display: none; +} +.navbar-expand .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; +} +.navbar-expand .offcanvas-top, +.navbar-expand .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; +} +.navbar-expand .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; +} .navbar-light .navbar-brand { - color: #3a3f44; } - .navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { - color: #3a3f44; } - + color: #3a3f44; +} +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: #3a3f44; +} .navbar-light .navbar-nav .nav-link { - color: rgba(0, 0, 0, 0.55); } - .navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { - color: #3a3f44; } - .navbar-light .navbar-nav .nav-link.disabled { - color: rgba(0, 0, 0, 0.3); } - + color: rgba(0, 0, 0, 0.55); +} +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: #3a3f44; +} +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} .navbar-light .navbar-nav .show > .nav-link, .navbar-light .navbar-nav .nav-link.active { - color: #3a3f44; } - + color: #3a3f44; +} .navbar-light .navbar-toggler { color: rgba(0, 0, 0, 0.55); - border-color: rgba(0, 0, 0, 0.1); } - + border-color: rgba(0, 0, 0, 0.1); +} .navbar-light .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} .navbar-light .navbar-text { - color: rgba(0, 0, 0, 0.55); } - .navbar-light .navbar-text a, - .navbar-light .navbar-text a:hover, - .navbar-light .navbar-text a:focus { - color: #3a3f44; } + color: rgba(0, 0, 0, 0.55); +} +.navbar-light .navbar-text a, +.navbar-light .navbar-text a:hover, +.navbar-light .navbar-text a:focus { + color: #3a3f44; +} .navbar-dark .navbar-brand { - color: #fff; } - .navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { - color: #fff; } - + color: #fff; +} +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} .navbar-dark .navbar-nav .nav-link { - color: rgba(255, 255, 255, 0.55); } - .navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { - color: #fff; } - .navbar-dark .navbar-nav .nav-link.disabled { - color: rgba(255, 255, 255, 0.25); } - + color: rgba(255, 255, 255, 0.55); +} +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: #fff; +} +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} .navbar-dark .navbar-nav .show > .nav-link, .navbar-dark .navbar-nav .nav-link.active { - color: #fff; } - + color: #fff; +} .navbar-dark .navbar-toggler { color: rgba(255, 255, 255, 0.55); - border-color: rgba(255, 255, 255, 0.1); } - + border-color: rgba(255, 255, 255, 0.1); +} .navbar-dark .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} .navbar-dark .navbar-text { - color: rgba(255, 255, 255, 0.55); } - .navbar-dark .navbar-text a, - .navbar-dark .navbar-text a:hover, - .navbar-dark .navbar-text a:focus { - color: #fff; } + color: rgba(255, 255, 255, 0.55); +} +.navbar-dark .navbar-text a, +.navbar-dark .navbar-text a:hover, +.navbar-dark .navbar-text a:focus { + color: #fff; +} diff --git a/webroot/css/themes/theme-vapor.css b/webroot/css/themes/theme-vapor.css index ebab0cb..f96c897 100644 --- a/webroot/css/themes/theme-vapor.css +++ b/webroot/css/themes/theme-vapor.css @@ -1,368 +1,569 @@ /* Callout */ .callout { border: 1px solid #e9ecef; - border-radius: .25rem; + border-radius: 0.25rem; background-color: #363636; - box-shadow: none; } + box-shadow: none; +} .callout-primary { border-left-color: #6f42c1; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-secondary { border-left-color: #ea39b8; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-success { border-left-color: #3cf281; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-info { border-left-color: #1ba2f6; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-warning { border-left-color: #ffc107; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-danger { border-left-color: #e44c55; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-light { border-left-color: #44d9e8; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} .callout-dark { border-left-color: #170229; - border-left-width: .25rem; - border-left-style: solid; } + border-left-width: 0.25rem; + border-left-style: solid; +} /* Toasts */ .toast { - min-width: 250px; } + min-width: 250px; +} .toast-primary { color: #21143a; background-color: #d4c6ec; - border-color: #c5b3e6; } - .toast-primary strong { - border-top-color: #b6a0e0; } + border-color: #c5b3e6; +} +.toast-primary strong { + border-top-color: #b6a0e0; +} .toast-secondary { color: #461137; background-color: #f9c4ea; - border-color: #f7b0e3; } - .toast-secondary strong { - border-top-color: #f599db; } + border-color: #f7b0e3; +} +.toast-secondary strong { + border-top-color: #f599db; +} .toast-success { color: #124927; background-color: #c5fbd9; - border-color: #b1facd; } - .toast-success strong { - border-top-color: #99f8be; } + border-color: #b1facd; +} +.toast-success strong { + border-top-color: #99f8be; +} .toast-info { color: #08314a; background-color: #bbe3fc; - border-color: #a4dafb; } - .toast-info strong { - border-top-color: #8cd0fa; } + border-color: #a4dafb; +} +.toast-info strong { + border-top-color: #8cd0fa; +} .toast-warning { color: #4d3a02; background-color: #ffecb5; - border-color: #ffe69c; } - .toast-warning strong { - border-top-color: #ffe083; } + border-color: #ffe69c; +} +.toast-warning strong { + border-top-color: #ffe083; +} .toast-danger { color: #44171a; background-color: #f7c9cc; - border-color: #f4b7bb; } - .toast-danger strong { - border-top-color: #f1a1a6; } + border-color: #f4b7bb; +} +.toast-danger strong { + border-top-color: #f1a1a6; +} .toast-light { color: #144146; background-color: #c7f4f8; - border-color: #b4f0f6; } - .toast-light strong { - border-top-color: #9debf3; } + border-color: #b4f0f6; +} +.toast-light strong { + border-top-color: #9debf3; +} .toast-dark { color: #07010c; background-color: #b9b3bf; - border-color: #a29aa9; } - .toast-dark strong { - border-top-color: #958c9d; } + border-color: #a29aa9; +} +.toast-dark strong { + border-top-color: #958c9d; +} /* Dropdown-item */ .dropdown-item.dropdown-item-primary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #6f42c1; } + .dropdown-item.dropdown-item-primary:hover { + color: #fff; + background-color: #5e38a4; } +======= + background-color: #6f42c1; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-primary:hover { color: #fff; - background-color: #6f42c1; } - + background-color: #6f42c1; +} .dropdown-item.dropdown-item-secondary { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #ea39b8; } + .dropdown-item.dropdown-item-secondary:hover { + color: #fff; + background-color: #c7309c; } +======= + background-color: #ea39b8; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-secondary:hover { color: #fff; - background-color: #ea39b8; } - + background-color: #ea39b8; +} .dropdown-item.dropdown-item-success { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #3cf281; } + .dropdown-item.dropdown-item-success:hover { + color: #fff; + background-color: #33ce6e; } +======= + background-color: #3cf281; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-success:hover { color: #fff; - background-color: #3cf281; } - + background-color: #3cf281; +} .dropdown-item.dropdown-item-info { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #1ba2f6; } + .dropdown-item.dropdown-item-info:hover { + color: #fff; + background-color: #178ad1; } +======= + background-color: #1ba2f6; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-info:hover { color: #fff; - background-color: #1ba2f6; } - + background-color: #1ba2f6; +} .dropdown-item.dropdown-item-warning { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #ffc107; } + .dropdown-item.dropdown-item-warning:hover { + color: #fff; + background-color: #d9a406; } +======= + background-color: #ffc107; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-warning:hover { color: #fff; - background-color: #ffc107; } - + background-color: #ffc107; +} .dropdown-item.dropdown-item-danger { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #e44c55; } + .dropdown-item.dropdown-item-danger:hover { + color: #fff; + background-color: #c24148; } +======= + background-color: #e44c55; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-danger:hover { color: #fff; - background-color: #e44c55; } - + background-color: #e44c55; +} .dropdown-item.dropdown-item-light { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #44d9e8; } + .dropdown-item.dropdown-item-light:hover { + color: #fff; + background-color: #3ab8c5; } +======= + background-color: #44d9e8; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-light:hover { color: #fff; - background-color: #44d9e8; } - + background-color: #44d9e8; +} .dropdown-item.dropdown-item-dark { color: #fff; text-decoration: none; +<<<<<<< HEAD background-color: #170229; } + .dropdown-item.dropdown-item-dark:hover { + color: #fff; + background-color: #140223; } +======= + background-color: #170229; +} +>>>>>>> 80cd93da404036ac08b645e105c750c6348e7c3f .dropdown-item.dropdown-item-outline-dark:hover { color: #fff; - background-color: #170229; } + background-color: #170229; +} /* Progress Timeline */ .progress-timeline { - padding: 0.2em 0.2em 0.5em 0.2em; } - .progress-timeline ul { - position: relative; - padding: 0; } - .progress-timeline li { - list-style-type: none; - position: relative; } - .progress-timeline li.progress-inactive { - opacity: 0.5; } - .progress-timeline .progress-line { - height: 2px; } - .progress-timeline .progress-line.progress-inactive { - opacity: 0.5; } + padding: 0.2em 0.2em 0.5em 0.2em; +} +.progress-timeline ul { + position: relative; + padding: 0; +} +.progress-timeline li { + list-style-type: none; + position: relative; +} +.progress-timeline li.progress-inactive { + opacity: 0.5; +} +.progress-timeline .progress-line { + height: 2px; +} +.progress-timeline .progress-line.progress-inactive { + opacity: 0.5; +} /* Forms severity */ .form-control.is-invalid.info { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%231ba2f6' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%231ba2f6' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.info:focus { - border-color: #1ba2f6; - box-shadow: 0 0 0 0.25rem rgba(27, 162, 246, 0.25); } - + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%231ba2f6' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%231ba2f6' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.info:focus { + border-color: #1ba2f6; + box-shadow: 0 0 0 0.25rem rgba(27, 162, 246, 0.25); +} .form-control.is-invalid.warning { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); } - .form-control.is-invalid.warning:focus { - border-color: #ffc107; - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ffc107' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); +} +.form-control.is-invalid.warning:focus { + border-color: #ffc107; + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).info, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%231ba2f6'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%231ba2f6' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).info:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.info:focus { - box-shadow: 0 0 0 0.25rem rgba(27, 162, 246, 0.25); } - + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).info:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.info:focus { + box-shadow: 0 0 0 0.25rem rgba(27, 162, 246, 0.25); +} .form-select.is-invalid:not([multiple]):not([size]).warning, -.form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning { +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e"); - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } - .form-select.is-invalid:not([multiple]):not([size]).warning:focus, - .form-select.is-invalid:not([multiple])[size="1"] -.form-select.is-invalid.warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); } + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-select.is-invalid:not([multiple]):not([size]).warning:focus, +.form-select.is-invalid:not([multiple])[size="1"] .form-select.is-invalid.warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25); +} .form-check-input.is-invalid.info { - border-color: #1ba2f6; } - + border-color: #1ba2f6; +} .form-check-input.is-invalid.info:checked { - background-color: #1ba2f6; } - + background-color: #1ba2f6; +} .form-check-input.is-invalid.info ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.info:focus { - box-shadow: 0 0 0 0.2rem rgba(27, 162, 246, 0.25); } - + box-shadow: 0 0 0 0.2rem rgba(27, 162, 246, 0.25); +} .form-check-input.is-invalid.warning { - border-color: #ffc107; } - + border-color: #ffc107; +} .form-check-input.is-invalid.warning:checked { - background-color: #ffc107; } - + background-color: #ffc107; +} .form-check-input.is-invalid.warning ~ .form-check-label { - color: unset; } - + color: unset; +} .form-check-input.is-invalid.warning:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.25); +} /* Utilities */ .mw-75 { - max-width: 75% !important; } + max-width: 75% !important; +} + +.mw-66 { + max-width: 66% !important; } .mw-50 { - max-width: 50% !important; } + max-width: 50% !important; +} + +.mw-33 { + max-width: 33% !important; } .mw-25 { - max-width: 25% !important; } + max-width: 25% !important; +} .mh-75 { - max-height: 75% !important; } + max-height: 75% !important; +} + +.mh-66 { + max-height: 66% !important; } .mh-50 { - max-height: 50% !important; } + max-height: 50% !important; +} + +.mh-33 { + max-height: 33% !important; } .mh-25 { - max-height: 25% !important; } + max-height: 25% !important; +} .p-abs-center-y { top: 50%; - transform: translateY(-50%); } + transform: translateY(-50%); +} .p-abs-center-x { left: 50%; - transform: translateX(-50%); } + transform: translateX(-50%); +} .p-abs-center-both { top: 50%; left: 50%; - transform: translateX(-50%) translateY(-50%); } + transform: translateX(-50%) translateY(-50%); +} + +.fs-7 { + font-size: .875rem !important; } + +.fs-8 { + font-size: .7rem !important; } + +.btn-xs, .btn-group-xs > .btn { + padding: 0.1rem; + font-size: 0.7rem; + border-radius: 0.15rem; + line-height: 1.15; } + +.btn-check:focus + .btn.btn-xs, .btn.btn-xs:focus { + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } + +.multi-metafields-container { + position: relative; } + @media (min-width: 576px) { + .multi-metafields-container::before { + content: none !important; } } + .multi-metafields-container::before { + border-style: solid; + border-color: #ea39b8; + border-width: 2px 0px 2px 2px; + border-radius: 3px 0px 0px 3px; + opacity: 0.5; + position: absolute; + content: ' '; + width: 0.5rem; + height: calc(100% - 33px); + transform: translate(0px, 18px); } + .multi-metafields-container > .multi-metafield-container { + position: relative; } + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + content: ' '; } + @media (min-width: 576px) { + .multi-metafields-container > .multi-metafield-container > .multi-metafield-input-container::before { + background-color: #ea39b8; + opacity: 0.5; + position: absolute; + width: 0.25rem; + transform: translateX(calc(1.5rem * -.5 + 3px)); + height: calc(100% + 4px); } } + @media (max-width: 575.98px) { + .multi-metafields-container > .multi-metafield-container:not(:first-child) label.form-label { + display: none; } } + .multi-metafields-container > .multi-metafield-container:first-child > .multi-metafield-input-container::before { + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .multi-metafields-container > .multi-metafield-container:last-child > .multi-metafield-input-container::before { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + height: 100%; } /* Body */ .panel { background-color: #363636; border: 1px solid #454545; - box-shadow: none; } + box-shadow: none; +} .loading-overlay { background-color: #170229; - opacity: 0.65; } + opacity: 0.65; +} /* Top navbar */ .top-navbar { - background-color: #6f42c1; } + background-color: #6f42c1; +} .center-navbar nav.header-breadcrumb { - color: #fff; } + color: #fff; +} header.top-navbar .header-menu > a:hover, header.top-navbar .header-breadcrumb .header-breadcrumb-item > a:hover { - color: #d6d6d6 !important; } + color: #d6d6d6 !important; +} .top-navbar .center-navbar nav.header-breadcrumb li.header-breadcrumb-item a { - color: #fff; } + color: #fff; +} .top-navbar .right-navbar .header-menu a.nav-link { - color: #fff; } + color: #fff; +} .top-navbar .left-navbar .navbar-brand img { - filter: invert(1); } + filter: invert(1); +} .top-navbar .left-navbar .navbar-brand:hover img { - filter: invert(1) drop-shadow(0px 0px 3px #fff); } + filter: invert(1) drop-shadow(0px 0px 3px #fff); +} .top-navbar .composed-app-icon-container > .app-icon { - background-color: #fff; } + background-color: #fff; +} .breadcrumb-link-container { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 2px 6px 0 rgba(0, 0, 0, 0.12); - background-color: #44d9e8; } + background-color: #44d9e8; +} /* Sidebar */ .sidebar { - transition: width .08s linear; + transition: width 0.08s linear; box-shadow: none; - background-color: #170229; } + background-color: #170229; +} .sidebar ~ main.content:after { - background: #000; } + background: #000; +} .sidebar .sidebar-wrapper { - border-right: 1px solid none; } + border-right: 1px solid none; +} .sidebar .sidebar-wrapper { - border-right: 1px solid rgba(0, 0, 0, 0.125); } + border-right: 1px solid rgba(0, 0, 0, 0.125); +} .sidebar ul.sidebar-elements li > a.sidebar-link { - color: #fff; } + color: #fff; +} .sidebar ul.sidebar-elements li > a.sidebar-link.active { background-color: #343a40; - color: #3cf281; } + color: #3cf281; +} .sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child { background-color: #343a40; - color: #3cf281; } + color: #3cf281; +} + +.sidebar ul.sidebar-elements li > a.sidebar-link.have-active-child::after { + background-color: #6f42c1; } .sidebar ul.sidebar-elements li > a.sidebar-link:hover { background-color: #495057; - color: #3cf281; } + color: #3cf281; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child { - background-color: unset; } + background-color: unset; +} .sidebar.expanded ul.sidebar-elements li > a.sidebar-link.have-active-child:hover, .sidebar:hover ul.sidebar-elements li > a.sidebar-link.have-active-child:hover { - background-color: #495057; } + background-color: #495057; +} ul.sidebar-elements li > a.sidebar-link.active::after { - background-color: #6f42c1; } + background-color: #6f42c1; +} .lock-sidebar > a.btn { - background-color: unset; } + background-color: unset; +} diff --git a/webroot/docs/openapi.yaml b/webroot/docs/openapi.yaml new file mode 100644 index 0000000..8077ce7 --- /dev/null +++ b/webroot/docs/openapi.yaml @@ -0,0 +1,2055 @@ +openapi: 3.0.0 +info: + version: 1.3.0 + title: Cerebrate Project API + description: | + Cerebrate is an open-source platform meant to act as a trusted contact information provider and interconnection orchestrator for other security tools. + +servers: + - url: https://cerebrate.local + +tags: + - name: Individuals + description: "Individuals are natural persons. They are meant to describe the basic information about an individual that may or may not be a user of this community. Users in genral require an individual object to identify the person behind them - however, no user account is required to store information about an individual. Individuals can have affiliations to organisations and broods as well as cryptographic keys, using which their messages can be verified and which can be used to securely contact them." + - name: Users + description: "Users enrolled in this Cerebrate instance." + - name: Organisations + description: "Organisations can be equivalent to legal entities or specific individual teams within such entities. Their purpose is to relate individuals to their affiliations and for release control of information using the Trust Circles." + - name: Tags + description: "Tags can be attached to entity to quickly classify them, allowing further filtering and searches." + - name: Inbox + description: "Inbox messages represent A list of requests to be manually processed." + - name: SharingGroups + description: "Sharing groups are distribution lists usable by tools that can exchange information with a list of trusted partners. Create recurring or ad hoc sharing groups and share them with the members of the sharing group." + - name: Broods + description: "Cerebrate can connect to other Cerebrate instances to exchange trust information and to instrument interconnectivity between connected local tools. Each such Cerebrate instance with its connected tools is considered to be a brood." + - name: EncryptionKeys + description: "Assign encryption keys to the user, used to securely communicate or validate messages coming from the user." + - name: AuthKeys + description: "Authkeys are used for API access. A user can have more than one authkey, so if you would like to use separate keys per tool that queries Cerebrate, add additional keys. Use the comment field to make identifying your keys easier." + +paths: + /individuals/index: + get: + summary: "Get individuals list" + operationId: getIndividuals + tags: + - Individuals + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/IndividualListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /individuals/view/{individualId}: + get: + summary: "Get individual by ID" + operationId: getIndividualById + tags: + - Individuals + parameters: + - $ref: "#/components/parameters/individualId" + responses: + "200": + $ref: "#/components/responses/IndividualResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /individuals/add: + post: + summary: "Add individual" + operationId: addIndividual + tags: + - Individuals + requestBody: + $ref: "#/components/requestBodies/CreateIndividualRequest" + responses: + "200": + $ref: "#/components/responses/IndividualResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /individuals/edit/{individualId}: + put: + summary: "Edit individual" + operationId: editIndividual + tags: + - Individuals + parameters: + - $ref: "#/components/parameters/individualId" + requestBody: + $ref: "#/components/requestBodies/EditIndividualRequest" + responses: + "200": + $ref: "#/components/responses/IndividualResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /individuals/delete/{individualId}: + delete: + summary: "Delete individual by ID" + operationId: deleteIndividualById + tags: + - Individuals + parameters: + - $ref: "#/components/parameters/individualId" + responses: + "200": + $ref: "#/components/responses/IndividualResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/index: + get: + summary: "Get users list" + operationId: getUsers + tags: + - Users + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/UserListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/view: + get: + summary: "Get information about the current user" + operationId: viewUserMe + tags: + - Users + responses: + "200": + $ref: "#/components/responses/UserResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/view/{userId}: + get: + summary: "Get information of a user by ID" + operationId: viewUserById + tags: + - Users + parameters: + - $ref: "#/components/parameters/userId" + responses: + "200": + $ref: "#/components/responses/UserResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/add: + post: + summary: "Add user" + operationId: addUser + tags: + - Users + requestBody: + $ref: "#/components/requestBodies/CreateUserRequest" + responses: + "200": + $ref: "#/components/responses/UserResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/edit: + put: + summary: "Edit current user" + operationId: editUser + tags: + - Users + requestBody: + $ref: "#/components/requestBodies/EditUserRequest" + responses: + "200": + $ref: "#/components/responses/UserResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/edit/{userId}: + put: + summary: "Edit current user" + operationId: editUserById + tags: + - Users + parameters: + - $ref: "#/components/parameters/userId" + requestBody: + $ref: "#/components/requestBodies/EditUserRequest" + responses: + "200": + $ref: "#/components/responses/UserResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /users/delete/{userId}: + delete: + summary: "Delete user by ID" + operationId: deleteUserById + tags: + - Users + parameters: + - $ref: "#/components/parameters/userId" + responses: + "200": + $ref: "#/components/responses/UserResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/add: + post: + summary: "Add organisation" + operationId: addOrganisation + tags: + - Organisations + requestBody: + $ref: "#/components/requestBodies/CreateOrganisationRequest" + responses: + "200": + $ref: "#/components/responses/OrganisationResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/edit/{organisationId}: + put: + summary: "Edit organisation" + operationId: editOrganisation + tags: + - Organisations + parameters: + - $ref: "#/components/parameters/organisationId" + requestBody: + $ref: "#/components/requestBodies/EditOrganisationRequest" + responses: + "200": + $ref: "#/components/responses/OrganisationResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/index: + get: + summary: "Get organisations" + operationId: getOrganisations + tags: + - Organisations + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/OrganisationListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/view/{organisationId}: + get: + summary: "View organisation by ID" + operationId: getOrganisationById + tags: + - Organisations + parameters: + - $ref: "#/components/parameters/organisationId" + responses: + "200": + $ref: "#/components/responses/OrganisationResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/delete/{organisationId}: + delete: + summary: "Delete organisation by ID" + operationId: deleteOrganisationById + tags: + - Organisations + parameters: + - $ref: "#/components/parameters/organisationId" + responses: + "200": + $ref: "#/components/responses/OrganisationResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/tag/{organisationId}: + post: + summary: "Tag organisation by ID" + operationId: tagOrganisationById + tags: + - Organisations + parameters: + - $ref: "#/components/parameters/organisationId" + requestBody: + $ref: "#/components/requestBodies/TagOrganisationRequest" + responses: + "200": + $ref: "#/components/responses/OrganisationResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /organisations/untag/{organisationId}: + post: + summary: "Remove organisation tag by ID" + operationId: untagOrganisationById + tags: + - Organisations + parameters: + - $ref: "#/components/parameters/organisationId" + requestBody: + $ref: "#/components/requestBodies/UntagOrganisationRequest" + responses: + "200": + $ref: "#/components/responses/OrganisationResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /tags/index: + get: + summary: "Get tags list" + operationId: getTags + tags: + - Tags + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/TagListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /inbox/index: + get: + summary: "Get inbox list" + operationId: getinbox + tags: + - Inbox + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/InboxListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /inbox/createEntry/User/Registration: + post: + summary: "Create user registration inbox entry" + operationId: createInboxEntry + tags: + - Inbox + requestBody: + $ref: "#/components/requestBodies/CreateUserRegistrationInboxEntryRequest" + responses: + "200": + $ref: "#/components/responses/CreateUserRegistrationInboxEntryResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /sharingGroups/index: + get: + summary: "Get a sharing groups list" + operationId: getSharingGroups + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/SharingGroupListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /sharingGroups/add: + post: + summary: "Add sharing group" + operationId: addSharingGroup + tags: + - SharingGroups + requestBody: + $ref: "#/components/requestBodies/CreateSharingGroupRequest" + responses: + "200": + $ref: "#/components/responses/IndividualResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /sharingGroups/view/{sharingGroupId}: + get: + summary: "Get sharing group by ID" + operationId: getSharingGroupById + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/sharingGroupId" + responses: + "200": + $ref: "#/components/responses/SharingGroupResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /sharingGroups/delete/{sharingGroupId}: + delete: + summary: "Delete sharing group by ID" + operationId: deleteSharingGroupById + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/sharingGroupId" + responses: + "200": + $ref: "#/components/responses/SharingGroupResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /sharingGroups/edit/{sharingGroupId}: + put: + summary: "Edit sharing group" + operationId: editSharingGroup + tags: + - SharingGroups + parameters: + - $ref: "#/components/parameters/sharingGroupId" + requestBody: + $ref: "#/components/requestBodies/EditSharingGroupRequest" + responses: + "200": + $ref: "#/components/responses/SharingGroupResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /broods/index: + get: + summary: "Get broods list" + operationId: getBroods + tags: + - Broods + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/BroodListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /broods/view/{broodId}: + get: + summary: "Get brood by ID" + operationId: getBroodById + tags: + - Broods + parameters: + - $ref: "#/components/parameters/broodId" + responses: + "200": + $ref: "#/components/responses/BroodResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /broods/add: + post: + summary: "Add brood" + operationId: addBrood + tags: + - Broods + requestBody: + $ref: "#/components/requestBodies/CreateBroodRequest" + responses: + "200": + $ref: "#/components/responses/BroodResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /broods/edit/{broodId}: + put: + summary: "Edit brood" + operationId: editBrood + tags: + - Broods + parameters: + - $ref: "#/components/parameters/broodId" + requestBody: + $ref: "#/components/requestBodies/EditBroodRequest" + responses: + "200": + $ref: "#/components/responses/BroodResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /broods/delete/{broodId}: + delete: + summary: "Delete brood by ID" + operationId: deleteBroodById + tags: + - Broods + parameters: + - $ref: "#/components/parameters/broodId" + responses: + "200": + $ref: "#/components/responses/BroodResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /broods/testConnection/{broodId}: + get: + summary: "Test brood connection by ID" + operationId: testBroodConnectionById + tags: + - Broods + parameters: + - $ref: "#/components/parameters/broodId" + responses: + "200": + $ref: "#/components/responses/TestBroodConnectionResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + # EncryptionKeys + /encryptionKeys/index: + get: + summary: "Get encryption keys list" + operationId: getEncryptionKeys + tags: + - EncryptionKeys + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/EncryptionKeyListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /encryptionKeys/view/{encryptionKeyId}: + get: + summary: "Get encryption key by ID" + operationId: getEncryptionKeyId + tags: + - EncryptionKeys + parameters: + - $ref: "#/components/parameters/encryptionKeyId" + responses: + "200": + $ref: "#/components/responses/EncryptionKeyResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /encryptionKeys/add: + post: + summary: "Add encryption key" + operationId: addEncryptionKey + tags: + - EncryptionKeys + requestBody: + $ref: "#/components/requestBodies/CreateEncryptionKeyRequest" + responses: + "200": + $ref: "#/components/responses/EncryptionKeyResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /encryptionKeys/edit/{encryptionKeyId}: + put: + summary: "Edit encryption key" + operationId: editEncryptionKey + tags: + - EncryptionKeys + parameters: + - $ref: "#/components/parameters/encryptionKeyId" + requestBody: + $ref: "#/components/requestBodies/EditEncryptionKeyRequest" + responses: + "200": + $ref: "#/components/responses/EncryptionKeyResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /encryptionKeys/delete/{encryptionKeyId}: + delete: + summary: "Delete encryption key by ID" + operationId: deleteEncryptionKeyById + tags: + - EncryptionKeys + parameters: + - $ref: "#/components/parameters/encryptionKeyId" + responses: + "200": + $ref: "#/components/responses/EncryptionKeyResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + # AuthKeys + /authKeys/index: + get: + summary: "Get auth keys list" + operationId: getAuthKeys + tags: + - AuthKeys + parameters: + - $ref: "#/components/parameters/quickFilter" + responses: + "200": + $ref: "#/components/responses/AuthKeyListResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /authKeys/add: + post: + summary: "Add auth keys" + operationId: addAuthKey + tags: + - AuthKeys + requestBody: + $ref: "#/components/requestBodies/CreateAuthKeyRequest" + responses: + "200": + $ref: "#/components/responses/AuthKeyResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + + /authKeys/delete/{authKeyId}: + delete: + summary: "Delete auth key by ID" + operationId: deleteAuthKeyById + tags: + - AuthKeys + parameters: + - $ref: "#/components/parameters/authKeyId" + responses: + "200": + $ref: "#/components/responses/AuthKeyResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "405": + $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + +components: + schemas: + # General + UUID: + type: string + format: uuid + maxLength: 36 + example: "c99506a6-1255-4b71-afa5-7b8ba48c3b1b" + + ID: + type: integer + format: int32 + example: 1 + + DateTime: + type: string + format: datetime + example: "2022-01-05T11:19:26+00:00" + + Email: + type: string + format: email + example: "user@example.com" + + ModelName: + type: string + enum: + - "Organisation" + - "User" + - "Individual" + - "EncryptionKey" + - "Role" + - "Tag" + - "SharingGroup" + - "Brood" + + # Individuals + IndividualFirstName: + type: string + example: "John" + + IndividualLastName: + type: string + example: "Doe" + + IndividualFullName: + type: string + example: "John Doe" + + IndividualPosition: + type: string + example: "Security Analyst" + + Individual: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + email: + $ref: "#/components/schemas/Email" + first_name: + $ref: "#/components/schemas/IndividualFirstName" + last_name: + $ref: "#/components/schemas/IndividualLastName" + full_name: + $ref: "#/components/schemas/IndividualFullName" + position: + $ref: "#/components/schemas/IndividualPosition" + tags: + $ref: "#/components/schemas/TagList" + aligments: + $ref: "#/components/schemas/AligmentList" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + # Users + Username: + type: string + example: "admin" + + IndividualList: + type: array + items: + $ref: "#/components/schemas/Individual" + + User: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + username: + $ref: "#/components/schemas/Username" + role_id: + $ref: "#/components/schemas/ID" + individual_id: + $ref: "#/components/schemas/ID" + disabled: + type: boolean + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + organisation_id: + $ref: "#/components/schemas/ID" + organisation: + $ref: "#/components/schemas/Organisation" + individual: + $ref: "#/components/schemas/Individual" + role: + $ref: "#/components/schemas/Role" + # user_settings: TODO + # user_settings_by_name: TODO + # user_settings_by_name_with_fallback: TODO + + UserList: + type: array + items: + $ref: "#/components/schemas/User" + + # Organisations + OrganisationName: + type: string + + OrganisationUrl: + type: string + + OrganisationSector: + type: string + nullable: true + + OrganisationType: + type: string + nullable: true + + OrganisationContacts: + type: string + nullable: true + + OrganisationNationality: + type: string + nullable: true + + Organisation: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/OrganisationName" + url: + $ref: "#/components/schemas/OrganisationUrl" + nationality: + $ref: "#/components/schemas/OrganisationNationality" + sector: + $ref: "#/components/schemas/OrganisationSector" + type: + $ref: "#/components/schemas/OrganisationType" + contacts: + $ref: "#/components/schemas/OrganisationContacts" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + tags: + $ref: "#/components/schemas/TagList" + aligments: + $ref: "#/components/schemas/AligmentList" + + OrganisationList: + type: array + items: + $ref: "#/components/schemas/Organisation" + + # Tags + TagName: + type: string + example: "white" + + TagNamespace: + type: string + nullable: true + example: "tlp" + + TagPredicate: + type: string + nullable: true + + TagValue: + type: string + nullable: true + + TagColour: + type: string + example: "FFFFFF" + + TagTextColour: + type: string + example: "white" + + Tag: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + name: + $ref: "#/components/schemas/TagName" + namespace: + $ref: "#/components/schemas/TagNamespace" + predicate: + $ref: "#/components/schemas/TagPredicate" + value: + $ref: "#/components/schemas/TagValue" + colour: + $ref: "#/components/schemas/TagColour" + text_colour: + $ref: "#/components/schemas/TagTextColour" + counter: + type: integer + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + TagList: + type: array + items: + $ref: "#/components/schemas/Tag" + + # Alignments + Alignment: + type: object + + AligmentList: + type: array + items: + $ref: "#/components/schemas/Alignment" + + # Roles + RoleName: + type: string + maxLength: 255 + example: "admin" + + Role: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + name: + $ref: "#/components/schemas/RoleName" + is_default: + type: boolean + perm_admin: + type: boolean + perm_sync: + type: boolean + perm_org_admin: + type: boolean + + # Inbox + InboxScope: + type: string + enum: + - "User" + - "LocalTool" + - "Brood" + - "Proposal" + - "Synchronisation" + + InboxAction: + type: string + enum: + - "Registration" + - "IncomingConnectionRequest" + - "AcceptedRequest" + - "DeclinedRequest" + - "Synchronisation" + - "OneWaySynchronization" + - "ProposalEdit" + - "DataExchange" + + InboxTitle: + type: string + + InboxOrigin: + type: string + + InboxComment: + type: string + nullable: true + + InboxDescription: + type: string + nullable: true + + Inbox: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + scope: + $ref: "#/components/schemas/InboxScope" + action: + $ref: "#/components/schemas/InboxAction" + title: + $ref: "#/components/schemas/InboxTitle" + origin: + $ref: "#/components/schemas/InboxOrigin" + comment: + $ref: "#/components/schemas/InboxComment" + description: + $ref: "#/components/schemas/InboxDescription" + user_id: + $ref: "#/components/schemas/ID" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + UserRegistrationInbox: + type: object + allOf: + - $ref: "#/components/schemas/Inbox" + - type: object + properties: + data: + type: object + properties: + email: + type: string + format: email + password: + type: string + user: + $ref: "#/components/schemas/User" + local_tool_connector_name: + type: string + nullable: true + + IncomingConnectionRequestInbox: + type: object + allOf: + - $ref: "#/components/schemas/Inbox" + - type: object + properties: + data: + type: object + properties: + connectorName: + type: string + enum: + - "MispConnector" + cerebrateURL: + type: string + example: "http://192.168.0.1" + local_tool_id: + type: integer + remote_tool_id: + type: integer + + InboxList: + type: array + items: + anyOf: + - $ref: "#/components/schemas/UserRegistrationInbox" + - $ref: "#/components/schemas/IncomingConnectionRequestInbox" + + # SharingGroups + SharingGroupName: + type: string + + SharingGroupReleasability: + type: string + + SharingGroupDescription: + type: string + + SharingGroup: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/SharingGroupName" + releasability: + $ref: "#/components/schemas/SharingGroupReleasability" + description: + $ref: "#/components/schemas/SharingGroupDescription" + organisation_id: + $ref: "#/components/schemas/ID" + user_id: + $ref: "#/components/schemas/ID" + active: + type: boolean + local: + type: boolean + sharing_group_orgs: + type: array + items: + $ref: "#/components/schemas/Organisation" + user: + $ref: "#/components/schemas/User" + organisation: + $ref: "#/components/schemas/Organisation" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + SharingGroupList: + type: array + items: + $ref: "#/components/schemas/SharingGroup" + + # Broods + BroodName: + type: string + + BroodDescription: + type: string + + BroodUrl: + type: string + + BroodIsTrusted: + type: boolean + description: "Trusted upstream source" + + BroodIsPull: + type: boolean + description: "Enable pulling of trust information" + + Brood: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/BroodName" + url: + $ref: "#/components/schemas/BroodUrl" + description: + $ref: "#/components/schemas/BroodDescription" + organisation_id: + $ref: "#/components/schemas/ID" + trusted: + $ref: "#/components/schemas/BroodIsTrusted" + pull: + $ref: "#/components/schemas/BroodIsPull" + skip_proxy: + type: boolean + authkey: + $ref: "#/components/schemas/AuthKeyRaw" + organisation: + $ref: "#/components/schemas/Organisation" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + BroodList: + type: array + items: + $ref: "#/components/schemas/Brood" + + # EncryptionKeys + EncryptionKeyType: + type: string + enum: + - "pgp" + - "smime" + + EncryptionKeyValue: + type: string + example: | + -----BEGIN PGP PUBLIC KEY BLOCK----- + ... + -----END PGP PUBLIC KEY BLOCK----- + + EncryptionKeyExpiration: + type: integer + description: "UNIX timestamp or null of there is no expiration" + nullable: true + + EncryptionKey: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + type: + $ref: "#/components/schemas/EncryptionKeyType" + encryption_key: + $ref: "#/components/schemas/EncryptionKeyValue" + revoked: + type: boolean + expires: + $ref: "#/components/schemas/EncryptionKeyExpiration" + owner_id: + $ref: "#/components/schemas/ID" + owner_model: + $ref: "#/components/schemas/ModelName" + created: + $ref: "#/components/schemas/DateTime" + modified: + $ref: "#/components/schemas/DateTime" + + EncryptionKeyList: + type: array + items: + $ref: "#/components/schemas/EncryptionKey" + + # AuthKeys + AuthKeyRaw: + type: string + + AuthKeyHashed: + type: string + + AuthKeyExpiration: + type: integer + description: "0 or UNIX timestamp" + example: 0 + + AuthKeyCreatedAt: + type: integer + description: "UNIX timestamp" + + AuthKeyComment: + type: string + + AuthKey: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + uuid: + $ref: "#/components/schemas/UUID" + authkey: + $ref: "#/components/schemas/AuthKeyHashed" + authkey_start: + type: string + example: abcd + authkey_end: + type: string + example: abcd + created: + $ref: "#/components/schemas/AuthKeyCreatedAt" + expiration: + $ref: "#/components/schemas/AuthKeyExpiration" + type: integer + description: "0 or UNIX timestamp" + user_id: + $ref: "#/components/schemas/ID" + comment: + $ref: "#/components/schemas/AuthKeyComment" + user: + $ref: "#/components/schemas/User" + + AuthKeyList: + type: array + items: + $ref: "#/components/schemas/AuthKey" + + # Errors + ApiError: + type: object + required: + - message + - url + - code + properties: + message: + type: string + url: + type: string + example: "/users" + code: + type: integer + example: 500 + + UnauthorizedApiError: + type: object + required: + - message + - url + - code + properties: + message: + type: string + example: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header." + url: + type: string + example: "/users" + code: + type: integer + example: 403 + + MethodNotAllowedApiError: + type: object + required: + - message + - url + - code + properties: + message: + type: string + example: "You do not have permission to use this functionality." + url: + type: string + example: "/users/index" + code: + type: integer + example: 405 + + NotFoundApiError: + type: object + required: + - message + - url + - code + properties: + message: + type: string + example: "Invalid user" + url: + type: string + example: "/users/users/view/1234" + code: + type: integer + example: 404 + + parameters: + individualId: + name: individualId + in: path + description: "Numeric ID of the User" + required: true + schema: + $ref: "#/components/schemas/ID" + + userId: + name: userId + in: path + description: "Numeric ID of the User" + required: true + schema: + $ref: "#/components/schemas/ID" + + organisationId: + name: organisationId + in: path + description: "Numeric ID of the Organisation" + required: true + schema: + $ref: "#/components/schemas/ID" + + sharingGroupId: + name: sharingGroupId + in: path + description: "Numeric ID of the Sharing Group" + required: true + schema: + $ref: "#/components/schemas/ID" + + broodId: + name: broodId + in: path + description: "Numeric ID of the Brood" + required: true + schema: + $ref: "#/components/schemas/ID" + + encryptionKeyId: + name: encryptionKeyId + in: path + description: "Numeric ID of the EncryptionKey" + required: true + schema: + $ref: "#/components/schemas/ID" + + authKeyId: + name: authKeyId + in: path + description: "Numeric ID of the AuthKey" + required: true + schema: + $ref: "#/components/schemas/ID" + + quickFilter: + name: quickFilter + in: query + description: "Quick filter used to match multiple attributes such as name, description, emails, etc." + schema: + type: string + example: "user@example.com" + + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: Authorization + description: | + The authorization is performed by using the following header in the HTTP requests: + + Authorization: YOUR_API_KEY + + requestBodies: + # Individuals + CreateIndividualRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + email: + $ref: "#/components/schemas/Email" + first_name: + $ref: "#/components/schemas/IndividualFirstName" + last_name: + $ref: "#/components/schemas/IndividualLastName" + position: + $ref: "#/components/schemas/IndividualPosition" + + EditIndividualRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + email: + $ref: "#/components/schemas/IndividualLastName" + first_name: + $ref: "#/components/schemas/IndividualFirstName" + last_name: + type: boolean + position: + $ref: "#/components/schemas/IndividualPosition" + + # Users + CreateUserRequest: + required: true + content: + application/json: + schema: + type: object + properties: + individual_id: + $ref: "#/components/schemas/ID" + organisation_id: + $ref: "#/components/schemas/ID" + role_id: + $ref: "#/components/schemas/ID" + disabled: + type: boolean + username: + $ref: "#/components/schemas/Username" + password: + type: string + + EditUserRequest: + required: true + content: + application/json: + schema: + type: object + properties: + id: + $ref: "#/components/schemas/ID" + individual_id: + $ref: "#/components/schemas/ID" + organisation_id: + $ref: "#/components/schemas/ID" + role_id: + $ref: "#/components/schemas/ID" + disabled: + type: boolean + username: + $ref: "#/components/schemas/Username" + password: + type: string + + # Organisations + CreateOrganisationRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/OrganisationName" + url: + $ref: "#/components/schemas/OrganisationUrl" + nationality: + $ref: "#/components/schemas/OrganisationNationality" + sector: + $ref: "#/components/schemas/OrganisationSector" + type: + $ref: "#/components/schemas/OrganisationType" + contacts: + $ref: "#/components/schemas/OrganisationContacts" + + EditOrganisationRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/OrganisationName" + url: + $ref: "#/components/schemas/OrganisationUrl" + nationality: + $ref: "#/components/schemas/OrganisationNationality" + sector: + $ref: "#/components/schemas/OrganisationSector" + type: + $ref: "#/components/schemas/OrganisationType" + contacts: + $ref: "#/components/schemas/OrganisationContacts" + + TagOrganisationRequest: + required: true + content: + application/json: + schema: + type: object + properties: + tag_list: + type: string + description: "Stringified JSON array of the tag names to add." + example: '["red"]' + + UntagOrganisationRequest: + required: true + content: + application/json: + schema: + type: object + properties: + tag_list: + type: string + description: "Stringified JSON array of the tag names to remove." + example: '["red"]' + + # Inbox + CreateUserRegistrationInboxEntryRequest: + description: "Create user registration inbox entry request" + content: + application/json: + schema: + type: object + properties: + email: + type: string + format: email + password: + type: string + + # SharingGroups + CreateSharingGroupRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/SharingGroupName" + releasability: + $ref: "#/components/schemas/SharingGroupReleasability" + description: + $ref: "#/components/schemas/SharingGroupDescription" + organisation_id: + $ref: "#/components/schemas/ID" + user_id: + $ref: "#/components/schemas/ID" + active: + type: boolean + local: + type: boolean + + EditSharingGroupRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/SharingGroupName" + releasability: + $ref: "#/components/schemas/SharingGroupReleasability" + description: + $ref: "#/components/schemas/SharingGroupDescription" + organisation_id: + $ref: "#/components/schemas/ID" + user_id: + $ref: "#/components/schemas/ID" + active: + type: boolean + local: + type: boolean + + # Broods + CreateBroodRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/BroodName" + url: + $ref: "#/components/schemas/BroodUrl" + description: + $ref: "#/components/schemas/BroodDescription" + organisation_id: + $ref: "#/components/schemas/ID" + trusted: + $ref: "#/components/schemas/BroodIsTrusted" + pull: + $ref: "#/components/schemas/BroodIsPull" + skip_proxy: + type: boolean + authkey: + $ref: "#/components/schemas/AuthKeyRaw" + + EditBroodRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + name: + $ref: "#/components/schemas/BroodName" + url: + $ref: "#/components/schemas/BroodUrl" + description: + $ref: "#/components/schemas/BroodDescription" + organisation_id: + $ref: "#/components/schemas/ID" + trusted: + $ref: "#/components/schemas/BroodIsTrusted" + pull: + $ref: "#/components/schemas/BroodIsPull" + skip_proxy: + type: boolean + authkey: + $ref: "#/components/schemas/AuthKeyRaw" + + CreateEncryptionKeyRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + type: + $ref: "#/components/schemas/EncryptionKeyType" + encryption_key: + $ref: "#/components/schemas/EncryptionKeyValue" + revoked: + type: boolean + expires: + $ref: "#/components/schemas/EncryptionKeyExpiration" + owner_id: + $ref: "#/components/schemas/ID" + owner_model: + $ref: "#/components/schemas/ModelName" + + EditEncryptionKeyRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + type: + $ref: "#/components/schemas/EncryptionKeyType" + encryption_key: + $ref: "#/components/schemas/EncryptionKeyValue" + revoked: + type: boolean + expires: + $ref: "#/components/schemas/EncryptionKeyExpiration" + owner_id: + $ref: "#/components/schemas/ID" + owner_model: + $ref: "#/components/schemas/ModelName" + + # AuthKeys + CreateAuthKeyRequest: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + $ref: "#/components/schemas/UUID" + authkey: + $ref: "#/components/schemas/AuthKeyRaw" + expiration: + $ref: "#/components/schemas/AuthKeyExpiration" + user_id: + $ref: "#/components/schemas/ID" + comment: + $ref: "#/components/schemas/AuthKeyComment" + + responses: + # Individuals + IndividualResponse: + description: "Individual response" + content: + application/json: + schema: + $ref: "#/components/schemas/Individual" + + IndividualListResponse: + description: "Individuals list response" + content: + application/json: + schema: + $ref: "#/components/schemas/IndividualList" + + # Users + UserResponse: + description: "User response" + content: + application/json: + schema: + $ref: "#/components/schemas/User" + + UserListResponse: + description: "Users list response" + content: + application/json: + schema: + $ref: "#/components/schemas/UserList" + + # Organisations + OrganisationResponse: + description: "Organisation response" + content: + application/json: + schema: + $ref: "#/components/schemas/Organisation" + + OrganisationListResponse: + description: "Organisations list response" + content: + application/json: + schema: + $ref: "#/components/schemas/OrganisationList" + + # Tags + TagResponse: + description: "Tag response" + content: + application/json: + schema: + $ref: "#/components/schemas/Tag" + + TagListResponse: + description: "Tags list response" + content: + application/json: + schema: + $ref: "#/components/schemas/TagList" + + # Inbox + UserRegistrationInboxResponse: + description: "User registration inbox response" + content: + application/json: + schema: + $ref: "#/components/schemas/UserRegistrationInbox" + + IncomingConnectionRequestInboxResponse: + description: "Incoming connection request inbox response" + content: + application/json: + schema: + $ref: "#/components/schemas/IncomingConnectionRequestInbox" + + InboxListResponse: + description: "Inbox list response" + content: + application/json: + schema: + $ref: "#/components/schemas/InboxList" + + CreateUserRegistrationInboxEntryResponse: + description: "Inbox response" + content: + application/json: + schema: + type: object + properties: + data: + allOf: + - $ref: "#/components/schemas/UserRegistrationInbox" + - properties: + local_tool_connector_name: + type: string + nullable: true + success: + type: boolean + message: + type: string + example: "User account creation requested. Please wait for an admin to approve your account." + errors: + type: array + items: + type: object + # TODO: describe + + # SharingGroups + SharingGroupResponse: + description: "Sharing group response" + content: + application/json: + schema: + $ref: "#/components/schemas/SharingGroup" + + SharingGroupListResponse: + description: "Sharing groups list response" + content: + application/json: + schema: + $ref: "#/components/schemas/SharingGroupList" + + # Broods + BroodResponse: + description: "Brood response" + content: + application/json: + schema: + $ref: "#/components/schemas/Brood" + + BroodListResponse: + description: "Brood list response" + content: + application/json: + schema: + $ref: "#/components/schemas/BroodList" + + TestBroodConnectionResponse: + description: "Brood list response" + content: + application/json: + schema: + type: object + properties: + code: + type: integer + description: "HTTP status code" + example: 200 + response: + type: object + properties: + version: + type: string + example: "0.1" + application: + type: string + example: "Cerebrate" + user: + type: string + example: "sync" + ping: + type: number + format: float + + # EncryptionKeys + EncryptionKeyResponse: + description: "Encryption key response" + content: + application/json: + schema: + $ref: "#/components/schemas/EncryptionKey" + + EncryptionKeyListResponse: + description: "Encryption key list response" + content: + application/json: + schema: + $ref: "#/components/schemas/EncryptionKeyList" + + # AuthKeys + AuthKeyResponse: + description: "Auth key response" + content: + application/json: + schema: + $ref: "#/components/schemas/AuthKey" + + AuthKeyListResponse: + description: "Auth key list response" + content: + application/json: + schema: + $ref: "#/components/schemas/AuthKeyList" + + # Errors + ApiErrorResponse: + description: "Unexpected API error" + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + + UnauthorizedApiErrorResponse: + description: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header." + content: + application/json: + schema: + $ref: "#/components/schemas/UnauthorizedApiError" + + MethodNotAllowedApiErrorResponse: + description: "Method not allowed. Your User Role is not allowed to access this resource." + content: + application/json: + schema: + $ref: "#/components/schemas/MethodNotAllowedApiError" + +security: + - ApiKeyAuth: [] diff --git a/webroot/js/CodeMirror/addon/display/placeholder.js b/webroot/js/CodeMirror/addon/display/placeholder.js new file mode 100644 index 0000000..d8e2dbd --- /dev/null +++ b/webroot/js/CodeMirror/addon/display/placeholder.js @@ -0,0 +1,78 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +(function (mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function (CodeMirror) { + CodeMirror.defineOption("placeholder", "", function (cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.on("blur", onBlur); + cm.on("change", onChange); + cm.on("swapDoc", onChange); + CodeMirror.on(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose = function () { onComposition(cm) }) + onChange(cm); + } else if (!val && prev) { + cm.off("blur", onBlur); + cm.off("change", onChange); + cm.off("swapDoc", onChange); + CodeMirror.off(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose) + clearPlaceholder(cm); + var wrapper = cm.getWrapperElement(); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); + } + + if (val && !cm.hasFocus()) onBlur(cm); + }); + + function clearPlaceholder(cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); + cm.state.placeholder = null; + } + } + function setPlaceholder(cm) { + clearPlaceholder(cm); + var elt = cm.state.placeholder = document.createElement("pre"); + elt.style.cssText = "height: 0; overflow: visible"; + elt.style.direction = cm.getOption("direction"); + elt.className = "CodeMirror-placeholder CodeMirror-line-like"; + var placeHolder = cm.getOption("placeholder") + if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder) + elt.appendChild(placeHolder) + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); + } + + function onComposition(cm) { + setTimeout(function () { + var empty = false + if (cm.lineCount() == 1) { + var input = cm.getInputField() + empty = input.nodeName == "TEXTAREA" ? !cm.getLine(0).length + : !/[^\u200b]/.test(input.querySelector(".CodeMirror-line").textContent) + } + if (empty) setPlaceholder(cm) + else clearPlaceholder(cm) + }, 20) + } + + function onBlur(cm) { + if (isEmpty(cm)) setPlaceholder(cm); + } + function onChange(cm) { + var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); + + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + } + + function isEmpty(cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === ""); + } +}); diff --git a/webroot/js/bootstrap-helper.js b/webroot/js/bootstrap-helper.js index a5c1133..1d5a2ae 100644 --- a/webroot/js/bootstrap-helper.js +++ b/webroot/js/bootstrap-helper.js @@ -185,10 +185,14 @@ class UIFactory { submissionReloaderModal(url, reloadUrl, $reloadedElement, $statusNode=null) { const successCallback = function ([data, modalObject]) { UI.reload(reloadUrl, $reloadedElement, $statusNode) - if (data.additionalData !== undefined && data.additionalData.displayOnSuccess !== undefined) { - UI.modal({ - rawHtml: data.additionalData.displayOnSuccess - }) + if (data.additionalData !== undefined) { + if (data.additionalData.displayOnSuccess !== undefined) { + UI.modal({ + rawHtml: data.additionalData.displayOnSuccess + }) + } else if (data.additionalData.redirect !== undefined) { + window.location = data.additionalData.redirect + } } } return UI.submissionModal(url, successCallback) @@ -308,7 +312,6 @@ class Toaster { return $(this).is($toast) }); if (hoveredElements.length > 0) { - console.log('Toast hovered. Not hidding') evt.preventDefault() setTimeout(() => { $toast.toast('hide') @@ -716,11 +719,11 @@ class ModalFactory { }) this.ajaxApi.push(tmpApi) } else { - this.ajaxApi.statusNode = $buttonConfirm[0] + this.ajaxApi.options.statusNode = $buttonConfirm[0] this.ajaxApi = [this.ajaxApi]; } } else { - this.ajaxApi.statusNode = $buttonConfirm[0] + this.ajaxApi.options.statusNode = $buttonConfirm[0] } return (evt) => { let confirmFunction = this.options.confirm @@ -764,7 +767,7 @@ class ModalFactory { return clickResult .then((data) => { if (data.success) { - selfModal.options.POSTSuccessCallback(data) + selfModal.options.POSTSuccessCallback([data, this]) } else { // Validation error selfModal.injectFormValidationFeedback(form, data.errors) return Promise.reject('Validation error'); @@ -800,7 +803,7 @@ class ModalFactory { return clickResult .then((data) => { if (data.success) { - this.options.POSTSuccessCallback(data) + this.options.POSTSuccessCallback([data, this]) } else { // Validation error this.injectFormValidationFeedback(form, data.errors) return Promise.reject('Validation error'); @@ -899,6 +902,9 @@ class OverlayFactory { const boundingRect = this.$node[0].getBoundingClientRect() this.$overlayWrapper.css('min-height', Math.max(boundingRect.height, 20)) this.$overlayWrapper.css('min-width', Math.max(boundingRect.width, 20)) + if (this.$node.hasClass('row')) { + this.$overlayWrapper.addClass('row') + } } this.$overlayContainer = $(OverlayFactory.overlayContainer) this.$overlayBg = $(OverlayFactory.overlayBg) diff --git a/webroot/js/main.js b/webroot/js/main.js index f2a5293..c4383ff 100644 --- a/webroot/js/main.js +++ b/webroot/js/main.js @@ -152,14 +152,156 @@ function focusSearchResults(evt) { } } +function saveSetting(statusNode, settingName, settingValue) { + const url = window.saveSettingURL + const data = { + name: settingName, + value: settingValue, + } + const APIOptions = { + statusNode: statusNode, + } + return AJAXApi.quickFetchAndPostForm(url, data, APIOptions) +} + +function openSaveBookmarkModal(bookmark_url = '') { + const url = '/user-settings/saveBookmark'; + UI.submissionModal(url).then(([modalFactory, ajaxApi]) => { + const $input = modalFactory.$modal.find('input[name="bookmark_url"]') + $input.val(bookmark_url) + }) +} + +function deleteBookmark(bookmark, forSidebar=false) { + const url = '/user-settings/deleteBookmark' + AJAXApi.quickFetchAndPostForm(url, { + bookmark_name: bookmark.name, + bookmark_url: bookmark.url, + }, { + provideFeedback: true, + statusNode: $('.bookmark-table-container'), + }).then((apiResult) => { + const url = `/userSettings/getBookmarks/${forSidebar ? '1' : '0'}` + UI.reload(url, $('.bookmark-table-container').parent()) + const theToast = UI.toast({ + variant: 'success', + title: apiResult.message, + bodyHtml: $('
').append( + $('').text('Cancel deletion operation.'), + $('